Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get touchEnd to behave just like mouseUp?

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";        

}
like image 672
Sarath Avatar asked Jul 11 '12 07:07

Sarath


1 Answers

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.

like image 194
zeusdeux Avatar answered Oct 04 '22 03:10

zeusdeux