touchend event not fired on iOS when it starts on a div - javascript

I have some problem with a touchend event on iOS:
var target;
window.addEvent('domready', function(){
target = $('mydiv');
target.addEvents({ 'touchstart': onTouchStart });
});
function onTouchStart(){
console.log('touch start');
target.addEvents({ 'touchend': onTouchEnd });
}
function onTouchEnd(){
console.log('touch end');
}
Everything should work fine, but touchend is not fired when I'm on this div.
This div is nothing special, it's just a wrapper for some images and has this CSS:
#albums-wrapper{ position: absolute; width: 10000px; height: 100%; }

In this line
target.addEvents({ 'touchend': onTouchEnd });
target is undefined, I believe

Related

Javascript mousemove event not triggered when in object

I hope your doing fine.
Here's my problem :
This code works fine :
var imageMover = {
mouseDown: function(e) {
e.target.addEventListener("mousemove", mouseMoved, false);
console.log('mouseDown');
},
mouseUp: function(e) {
e.target.removeEventListener("mousemove", mouseMoved, false);
console.log('mouseUp');
}
};
function mouseMoved(e) {
console.log("mouseMoved");
}
While this one is not :
var imageMover = {
mouseDown: function(e) {
e.target.addEventListener("mousemove", this.mouseMoved, false);
console.log('mouseDown');
},
mouseUp: function(e) {
e.target.removeEventListener("mousemove", this.mouseMoved, false);
console.log('mouseUp');
},
mouseMoved: function(e) {
console.log("mouseMoved");
}
};
To give a little more context: There are thumbnails you can click on.
When you click on it, the image is added to a container, and the events mouseUp and mouseDown are added to the image.
When someone click on the image, i'd like the event mouseMouve to be attached so I can follow the image position.
mouseUp and mouseDown are well attached, and well triggered, but mouseMouve only works when it is not inside my imageMover object.
It seems to be a scope problem, but I can't figure why it acts like that.
In advance, many thanks !
The this from this.mouseMoved is refering to the event target, which is the DOM element not the object storing the methods.
var imageMover = {
mouseDown: function(e) {
console.log( 'this is refering to => ', this );
e.target.addEventListener("mousemove", this.mouseMoved, false);
}
};
document.querySelector( '.container' ).addEventListener( 'mousedown', imageMover.mouseDown );
.container
{
width: 500px;
height: 100px;
border: 1px solid #000;
}
<div class="container"></div>

jquery and hammer.js ghost click when panning

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'});
});
...

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.

Adding New Element during `mousedown` event prevent triggering `click` event?

I am working with jquery events and I am adding a new element at the time of mousedown at the position of the mouse pointer and after adding the element the binded click event is not triggered.
Any suggestion is appreciable.
Thanks in advance.
Madhu
Code:
<div style="border:1px solid">Click</div>
<span></span>
<div class="vis" style="display:none">Hello</div>
<script>
var visualEle = $('div.vis');
visualEle.css({border:"1px solid"});
$('a').on("click", function (e) { e.preventDefault();});
$('div').on("mousedown", mDown);
$('div').on("mouseup",mUp);
function mDown(e) {
e.preventDefault();
visualEle.css({ left: 100, top: 0, display: "block" });
}
function mUp(e) {
e.preventDefault();
$('span').append('mouse up triggerd<br/>');
return false;
}
$('p').on("click",dClick);
function dClick(e) {
$('span').append('double click triggerd<br/>');
}
</script>
In the above code the click event is not triggered after the mousedown is completed.
according to this document
The click event is sent to an element when the mouse pointer is over the element, and the mouse button is pressed and released
in your case mouse point is over when mousedown happen but after that visualDiv moves under and mouse is released on this element.
possible solution I can think of thanks to #ArunPJohny is use $(this).trigger("click");
$('p').on("mousedown", function (e) {
_x = e.pageX;
_y = e.pageY;
visualDiv.css({
left: _x,
top: _y
});
$(this).trigger("click");
});
$('p').on("click", function (e) {
console.log(e.target)
});
Demo: http://jsfiddle.net/c5CRd/

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