i'm trying handle button click. "button" custom div can contain children. click callback should fire when user has both clicked , released inside element. if user clicks inside , drags , releases outside, handler should not fire. need working on both desktop , mobile, hence i'm using mousedown/mouseup
, touchstart/touchend
events.
i need change button class "pressed" "normal" if user releases outside, need add listener capture releasing event on document:
var $myelement = $("#myelement"); //this div , can 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 here return false; } else { //fixme alert("outside!"); //let event bubble } }); return false; });
it works fine clicks, not work expected touch events. i've tested in chrome android , when pressing on element, dragging out, "inside!" alert shown.
the problem in condition:
if ($target.is($myelement) || $target.parents().is($myelement)){
i'm trying check whether touchend
event has occurred in button or of the children. if button has no children, when clicking on , releasing outside, first part of or clause resolves true. if button has children , click in children, release in other part of screen, second part of clause true.
what wrong code?
thanks in advance.
update
i've tested in blackberry 10 same results. apparently target touchend
event button (or children), when i've clicked outside. how supposed work?
update
, here's why. what w3c docs event:
the target of event must same element received touchstart event when touch point placed on surface, if touch point has since moved outside interactive area of target element.
it makes no sense me, anyway explain problem. assuming touchend
event called on element finger released. possible detect finger release outside using different approach?
update
i've tried coordinates of touchevent
element there using document.elementfrompoint
. problem event not contain coordinates (the changedtouches
, touches
lists empty). i've thorougly inspected event in debugger , there's no way retrieve coords other original event's. thought cache last touchmove
event , coords there, again event has no own coordinates! why on earth these 2 events exist when useless? , i've tested approach in ios, android , bb10 identical results.
i've given up. i'll call callback if user clicked outside. can't believe 2013 guys , there's no (simple) way of doing this? use drag&drop api according this unsupported on mobile (gotta love mobile web development).
finally (almost) got working in bb10 , android. i've left trail of problems in question updates, sum up: touchend
event target same touchstart
, , comes without coordinates (the api designer reason decided "hide" them in originalevent
property :) . i'm retrieving touch end coordinates changedtouches[0].pagex
, changedtouches[0].pagey
, obtaining element finger released using document.elementfrompoint
. (before feeding method event coordinates must add scroll offset x , y). if element @ point button (or child of it), handle click.
var $myelement = $("#myelement"); //this div , can contain children. var startevent = touchdevice() ? "touchstart" : "mousedown"; var releaseevent = touchdevice() ? "touchend" : "mouseup"; $myelement.on(startevent, function(e){ $(this).addclass("pressed"); $(document).on(releaseevent, function listener(e){ $myelement.removeclass("pressed"); $(document).off(releaseevent, listener); var $target = null; if(e.type === "mouseup"){ $target = $(e.target); } else { var x = e.originalevent.changedtouches[0].pagex - window.pagexoffset; var y = e.originalevent.changedtouches[0].pagey - window.pageyoffset; var target = document.elementfrompoint(x, y); if(target){ $target = $(target); } } if ($target !== null && ($target.is($myelement) || $target.parents().is($myelement))){ //fixme alert("inside!"); //callback here return false; } else { //fixme alert("outside!"); } }); return false; });
now i've new problem: in ios somehow click events being duplicated. deserves different question (if not existing already).
Comments
Post a Comment