jquery and hammer.js ghost click when panning - javascript

I'm using jQuery 191 and Hammer JS 204. I have the following example scenario
<div> class="myDiv">
<div class="content">
<img>
</div>
</div>
Example JS
$('.myDiv').hammer({}).bind("pan", function(h) {
h.gesture.srcEvent.preventDefault();
});
$('.content img').on('click', function(){
console.log('i was clicked');
});
When I click on the image to start panning myDiv, Right after panend, the myDiv img click event gets fired.
I've tried to stopPropagation and stopImmediatePropagation but still couldn't get it to stop firing the click after i finish panning.

var hammering = false;
$('.myDiv').hammer({}).bind("pan", function(h) {
h.gesture.srcEvent.preventDefault();
}).bind("panstart", function(h) {
hammering = true;
}).bind("panend", function(h) {
setTimeout(function(){
hammering = false;
}, 300);
});
$('.content img').on('click', function(){
if(hammering) return false;
console.log('i was clicked');
});

Another way to avoid this ghost click is to create a pseudo class over the hammer target.
for example you can add class and the style something like
`.block:after {
content: " ";
background: transparent;
top: 0;
left: 0;
width: 250px;
height: 100%;
z-index: 2;
display: block;
position: absolute;
}`
when panstart and remove it when panend.
hope this trick will help others.

I find out a easy way could prevent click event while hammer.js panning:
disable div pointer-events while pan start, then enable it while pan end.
...
myPanGesture.on("panstart", function(ev) {
$(".tab-pane.active").css({'pointer-events':'none'});
});
...
myPanGesture.on("panend", function(ev) {
$(".tab-pane.active").css({'pointer-events':'auto'});
});
...

Related

How to set an element focused on click?

Basically I've a HTML 5 video element which on click I need to make it to be focused so I could control user keyboard triggers.
Here is my code:
$(function(){
var focused_vid;
$('.videoe').click(function(){ focused_vid = this });
$(document).keydown(function(e){
if (focused_vid){
// keyboard handler
}
});
});
Beside my video element I've a Text Box. The problem is once the video is focused It disable me to type on my Text Box and keeps triggering Key button for video handler even though I've:
$(window).click(function(e) {
$(e.srcElement.className).focus();
});
Regards :)
Do not use event.srcElement it's a non-standard IE property that Firefox doesn't support. Use event.target which is supported by all modern browsers. Try the .blur() method to take the focus away from the video. See the Snippet for example of how this could be done.
SNIPPET
$(function() {
var focused_vid;
$('#vid1').click(function() {
focused_vid = this
});
$(document).keydown(function(e) {
if (focused_vid) {
console.log('focused on ' + e.target.className);
}
});
});
$(window).click(function(e) {
$('#vid1').blur();
var tgt = e.target;
$(tgt).focus();
console.log('focused on ' + tgt.className);
});
/* This just to prevent the console from obscuring the demo */
input {
display: block;
}
.as-console-wrapper.as-console-wrapper {
margin-left:270px;
max-width: 250px;
height: 100vh;
color: blue;
font: 400 15px/1.3 Consolas;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id='inp1' class='txt' tabindex='2' placeholder="Enter this video's title">
<video id="vid1" class='vid' src="http://html5demos.com/assets/dizzy.mp4" controls tabindex='1' width='250'></video>
It might help others too.
var focused_vid=null;
$(function(){
$('.videoe').click(function(){ focused_vid = this });
$(document).keydown(function(e){
if (focused_vid){
// keyboard handler
}
});
});
function notfocused(){
focused_vid=null;
}
And later on we Can call notfocused method to remove handling keyboard buttons for video.
$(document).click(function(e) {
$('.videoe').blur();
var tgt = e.target;
$(tgt).focus();
if(tgt.className!="videoe")
notfocused();
});

click(function) doesn't work

I tried to do some animation with click function button and left/right arrow keyboard, just a simple left-right sliding animation. At first those script works perfectly, til I edit here and there, but not these JS.
When I run it again, only the keyboard based animation works, the button click animation wont work anymore.
$(document).ready(function(){
$('.btnright').click(function(){
$('.project').animate({
left: '-=150px',
});
});
$('.btnleft').click(function(){
$('.project').animate({
left: '+=150px',
});
});
});
I do test the the click function with alert, but the alert wont work too.
$(document).ready(function(){
$('.btnright').click(function(){
alert('right');
});
$('.btnleft').click(function(){
alert('left');
});
});
And I already check if I used the wrong class, but now, it's just allright.
<div class="btnright"><span class="material-icons">keyboard_arrow_right</span></div>
<div class="btnleft"><span class="material-icons">keyboard_arrow_left</span></div>
Here are the keyboard animation script, this keyboard script works fine
$(document).on("keydown", function(event) {
var x = event.keyCode;
if (x == 37) { // left
$('.project').animate({
left: '+=150px',
});
} else if (x == 39) { // right
$('.project').animate({
left: '-=150px',
});
}
});
Maybe I'm missing something. I'll appreciate for ya'll help. Thx.
Remove the trailing comma from your options object. Also, you need to specify the duration for the animation. Also, .project would need to be absolutely or relatively positioned (instead of default of static) for left to have an effect. So:
$('.btnright').click(function(){
$('.project').animate({
left: '-=150px'
}, 500);
});
With CSS:
.project {
position: relative;
}
Instead of:
$('.btnright').click(function(){
$('.project').animate({
left: '-=150px',
});
});
Codepen: http://codepen.io/anon/pen/WQzazR

How to get mouseup event after native drag event?

The implementation of the WHATWG drag and drop supports dragstart, drag and dragend events.
The dragend event fires when the draggable object returns to the original position, e.g. try dragging the red box as far as you can and release it. The dragend (and "END!" console.log message) will not fire until the draggable element returns to the original position (this is most visible in the Safari browser).
var handle = document.querySelector('#handle');
handle.addEventListener('dragend', function () {
console.log('END!');
});
#handle {
background: #f00; width: 100px; height: 100px;
}
<div id="handle" draggable="true"></div>
How do I capture the mouseup or whatever else event that would indicate the release of the drag handle without a delay?
I have tried variations of:
var handle = document.querySelector('#handle');
handle.addEventListener('dragend', function () {
console.log('END!');
});
handle.addEventListener('mouseup', function () {
console.log('Mouseup');
});
#handle {
background: #f00; width: 100px; height: 100px;
}
<div id="handle" draggable="true"></div>
Though, "mouseup" does not fire after dragstart.
The closest I got to finding an event that would fire instantly after the release of the handle is mousemove:
var handle = document.querySelector('#handle');
handle.addEventListener('dragend', function () {
console.log('END!');
});
window.addEventListener('mousemove', function () {
console.log('I will not fire during the drag event. I will fire after handle has been released and mouse is moved.');
});
#handle {
background: #f00; width: 100px; height: 100px;
}
<div id="handle" draggable="true"></div>
The problem is that this approach requires user to move the mouse.
The workaround is to enable drop on the document.body:
// #see https://developer.mozilla.org/en-US/docs/Web/Events/dragover
document.body.addEventListener('dragover', function (e) {
// Prevent default to allow drop.
e.preventDefault();
});
document.body.addEventListener('drop', function (e) {
// Prevent open as a link for some elements.
e.preventDefault();
});
Making document.body to listen for the drop event results in dragend thinking that you will move the element to the new position upon releasing the handle. Therefore, there is no delay between handle release and dragend.

JQuery - Clicking and dragging divs on a screen WITHOUT draggable

I'm currently working on a small project, with draggable divs. The code I've created seems to not be working, and it causes JQuery to stop responding.
Is there a nice and easy way to do this without using .draggable?
var hold = false;
//Drag Elements
$('#example').mousedown(function(){
hold = true;
});
$('#example').mouseup(function(){
hold = false;
});
$(document).on('mousemove', function(e){
$('#example').css({
while(hold){
left: e.pageX-50,
top: e.pageY-50
}
});
});
Thanks
Since Javascript is single-threaded, your while loop never exits, because the mouseup handler can't run while you're stuck in the mousemove handler.
Change while to if:
$(document).on('mousemove', function(e){
if (hold) {
$('#example').css({
left: e.pageX-50,
top: e.pageY-50
});
}
});

Stopping propagation of mousedown/mouseup from a click handler

Here's a DEMO.
I have two divs, an inner and an outer:
<div id="outer">
<div id="inner"></div>
</div>
With some CSS so you can see which is which:
#outer {
width: 250px;
height: 250px;
padding: 50px;
background: yellow;
}
#inner {
width: 250px;
height: 250px;
background: blue;
}
I try to stop propagation of mousedown and mouseup events from within a click handler like so:
$('#inner').on('click', function(e) {
e.stopPropagation();
$(this).css({'background': 'green'});
return false;
});
$('#outer').on('mousedown', function(e) {
$(this).css({'background': 'green'});
});
$('#outer').on('mouseup', function(e) {
$(this).css({'background': 'yellow'});
});
This doesn't seem possible. What does work is calling .stopPropagation from within other mousedown and mouseup calls, as shown here (another DEMO):
$('#inner').on('mousedown', function(e) {
e.stopPropagation();
return false;
});
$('#inner').on('mouseup', function(e) {
e.stopPropagation();
return false;
});
I may have already answered my own question, but I'm not sure if my approach is the best or most reasonable. Is this the right way to stop an event bubbling up to a mousedown and mouseup?
Yes. Since mouseclick and mousedown/mouseup are different events, you can't get at one from the other at all - you have to do it from within your own mousedown/mouseup handlers. What you can do is refactor that into a generic method to use in both places:
stopPropagation('#inner', 'mousedown');
stopPropagation('#inner', 'mouseup');
function stopPropagation(id, event) {
$(id).on(event, function(e) {
e.stopPropagation();
return false;
});
}

Categories

Resources