How to get touchEnd to behave just like mouseUp?

14,558

This was a fun question to tackle. Thanks for that. Here's what I have done. I have modified your touchmove handler as such:

   function onDocumentTouchMove(event) {
    onDocumentTouchMove.x = event.changedTouches[event.changedTouches.length - 1].clientX;
    onDocumentTouchMove.y = event.changedTouches[event.changedTouches.length - 1].clientY;
}

In this handler I'm saving the last co-ordinate that the user moved to. In all probability, this is the point at which the user took his finger, nose, knuckle, stylus, etc off the touch surface. These co-ordinates I then use in the handler for touchend to find the element that surrounds them.

    function onDocumentTouchEnd(event) {
    event.preventDefault();
    var elem = document.elementFromPoint(onDocumentTouchMove.x, onDocumentTouchMove.y);
    elem.style.background = "#ff0000";
}

I have utilized the document.elementFromPoint(mdn link) for this purpose. It is one of those golden yet fairly unknown methods provided to us by the CSSOM spec.

Here's the fiddle.

Share:
14,558

Related videos on Youtube

Sarath
Author by

Sarath

JavaScript :) :) :)

Updated on September 15, 2022

Comments

  • Sarath
    Sarath over 1 year

    On mouseUp or touchEnd I want to get the reference of the element on which that event happened.

    Demo

    In this example, you need to click on one element, drag mouse and released over another element. When the mouse is released, that element's background will change to red. My code works correctly for mouse events, but not on touch devices.

    When the touchStart is on one element and the finger is released over another element, I'm getting only the reference to the first element.

    What I need to change to make the touch events work exactly like the mouse events?

    var isMouseDown = false;    
    
    
    var panel1 = document.getElementById( 'panel1' );
    var panel2 = document.getElementById( 'panel2' );
    
    panel1.onmousedown = onDocumentMouseDown;
    panel1.onmouseup = onDocumentMouseUp;
    panel1.onmousemove = onDocumentMouseMove;   
    panel1.addEventListener( 'touchstart', onDocumentTouchStart, false );
    panel1.addEventListener( 'touchmove', onDocumentTouchMove, false );
    panel1.addEventListener( 'touchend', onDocumentTouchEnd, false );
    
    panel2.onmousedown = onDocumentMouseDown;
    panel2.onmouseup = onDocumentMouseUp;
    panel2.onmousemove = onDocumentMouseMove;
    panel2.addEventListener( 'touchstart', onDocumentTouchStart, false );
    panel2.addEventListener( 'touchmove', onDocumentTouchMove, false );
    panel2.addEventListener( 'touchend', onDocumentTouchEnd, false );
    
    
    
    function onDocumentMouseDown(event) {
        event.preventDefault();
        panel1.style.background="#2E442E";
        panel2.style.background="#5D855C";      
    }
    
    function onDocumentMouseUp(event) {
        event.preventDefault();
        this.style.background="#ff0000";
    }
    
    function onDocumentMouseMove( event ) {
    
    }   
    
    function onDocumentTouchStart( event ) {
        event.preventDefault();
        panel1.style.background="#2E442E";
        panel2.style.background="#5D855C";
    
    }
    
    function onDocumentTouchMove( event ) {     
    
    }
    
    function onDocumentTouchEnd( event ) {
        event.preventDefault();         
        this.style.background="#ff0000";        
    
    }
    
  • Justus Romijn
    Justus Romijn about 11 years
    Great find! I can confirm that this works on a Samsung Galaxy Tab with Chrome.
  • zeusdeux
    zeusdeux about 11 years
    Also works on opera, stock android browser and chrome on my one x.
  • zeusdeux
    zeusdeux about 11 years
    @isaac this here will still be the element where touchstart was fired hence it isn't a viable solution.
  • Sarath
    Sarath about 11 years
    yup.. i think this is a nice solution.. :) but i dont know whts the support for elementFromPoint..
  • zeusdeux
    zeusdeux about 11 years
  • BoltKey
    BoltKey over 6 years
    Thanks, it worked. It however didn't work on simple taps without hover, so I had to bind onDocumentTouchMove() to touchstart event as well.