I am trying to handle a button click. "button" is a custom div that can also contain children. The click callback should fire when the user clicked and released inside the element. If the user clicks inside and then drags and releases outside, the handler should not start. I need to get this to work both on the desktop and on mobile devices, so I use the mousedown/mouseup and touchstart/touchend .
I need to change the button class from โpressedโ to โnormalโ, even if the user goes outside, so I need to add a listener to capture the release event above the document:
var $myElement = $("#myelement"); //This is a div and can also contain children. $myElement.on("mousedown touchstart", function(e){ $(this).addClass("pressed"); $(document).on("mouseup touchend", function listener(e){ $myElement.removeClass("pressed"); $(document).off("mouseup touchend", listener); var $target = $(e.target); if ($target.is($myElement) || $target.parents().is($myElement)){ //FIXME alert("Inside!"); //do something here return false; } else { //FIXME alert("Outside!"); //let event bubble } }); return false; });
It works great with clicks, but with touch events it doesn't work properly. I tested this in Chrome for Android and when clicking on an element and then dragging "Inside!". A warning is displayed.
The problem is this condition:
if ($target.is($myElement) || $target.parents().is($myElement)){
I am trying to check if a touchend event has touchend in a button or any of these children. If the button has no children, when you click on it and then release it from the outside, the first part of the OR clause allows true. If the button has children, and I click on the children and then release it in any other part of the screen, the second part of the sentence is true.
What is wrong with this code?
Thanks at Advance.
UPDATE
I tested it also in BlackBerry 10 with the same results. Obviously, the target for the touchend event is a button (or children), even when I clicked outside. Is this the way it should work?
UPDATE
And that's why. This is what the W3C says about the event :
The purpose of this event should be the same element that received the touchstart event when this touch point was placed on the surface, even if the touch point has since been moved outside the interactive area of โโthe target element.
It makes no sense to me, but in any case it explains my problem. I assumed that the touchend event touchend be touchend over the element in which the finger was released. Is it possible to detect a fingerprint outside using a different approach?
UPDATE
I tried to get the touchevent coordinates to get the element there using document.elementFromPoint . The problem is that this event does not contain coordinates (the changedTouches and touches lists changedTouches empty). I definitely examined the event in the debugger, and there is no way to extract the coordinates from it, except for the original event. Then I thought that I could cache the last touchmove event and get the coordinates from there, but again this event does not have its own coordinates! Why on earth do these two events exist when they are useless? And I tested this approach on iOS, Android and BB10 with the same results.
I gave up. I will call a callback even if the user clicked outside. I canโt believe that these are guys from 2013, and there is no (easy) way to do this? I could use drag & drop api, but according to this , it is not supported on mobile devices (Gotta love mobile web development).