title: How to detect touchend event outside of an element
body: <p>I'm trying to handle a button click. The "button" is a custom div that can also contain children. The click callback should fire when the user has both clicked and released inside the element. If the user clicks inside and then drags and releases outside, the handler should not fire. I need to get this working on both desktop and mobile, hence I'm using <code>mousedown/mouseup</code> and <code>touchstart/touchend</code> events.</p>
  
  <p>I need to change the button class from "pressed" to "normal" even if the user releases outside, so I need to add a listener to capture the releasing event over the document:</p>
  
  <pre><code>    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;
      });
  </code></pre>
  
  <p>It works fine with clicks, but it does not work as expected with touch events. I've tested this in Chrome for Android and when pressing over the element, then dragging out, the "Inside!" alert is shown. </p>
  
  <p>The problem is in this condition:</p>
  
  <pre><code>if ($target.is($myElement) || $target.parents().is($myElement)){
  </code></pre>
  
  <p>I'm trying to check whether the <code>touchend</code> event has occurred in the button or any of the the children. If the button has no children, when clicking on it and then releasing outside, the first part of the OR clause resolves to true. If the button has children and I click in the children, then release in any other part of the screen, the second part of the clause is true.</p>
  
  <p>What is wrong with this code?</p>
  
  <p>Thanks in Advance.</p>
  
  <p>UPDATE<br/>
  I've tested it also in BlackBerry 10 with the same results. Apparently the target for the <code>touchend</code> event is the button (or the children), even when I've clicked outside. Is this how it is supposed to work?</p>
  
  <p>UPDATE<br/>
  And here's why. This is <a href="http://www.w3.org/TR/2011/WD-touch-events-20110505/#the-touchend-event" rel="noreferrer">what the W3C docs say about the event</a>:</p>
  
  <blockquote>
    <p><em>The target of this event must 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 moved outside the interactive area of the target element.</em> </p>
  </blockquote>
  
  <p>It makes no sense to me, but anyway this explain my problem. I was assuming the <code>touchend</code> event would be called over the element where the finger was released. Would it be possible to detect the finger release outside using a different approach? </p>
  
  <p>UPDATE<br/>
  I've tried to get the coordinates of the <code>touchevent</code> to get the element there using <code>document.elementFromPoint</code>. The problem is this event does not contain the coordinates (the <code>changedTouches</code> and <code>touches</code> lists are empty). I've thorougly inspected the event in the debugger and there's no way to retrieve coords from it other than the original event's. Then I thought I could cache the last <code>touchmove</code> event and get the coords from there, but again this event has no own coordinates! Why on Earth do these two events exist when they are useless? And I've tested this approach in iOS, Android and BB10 with identical results.</p>
  
  <p>I've given up.  I'll call the callback even if the user clicked outside. I can't believe it is 2013 guys and there's no (simple) way of doing this? I could use the drag&amp;drop api but according to <a href="http://caniuse.com/#feat=dragndrop" rel="noreferrer">this</a> it is unsupported on mobile (Gotta love mobile web development).</p>