Search code examples
javascriptgoogle-chromefirefoxtouchtouchscreen

handle both mouse and touch events on touch screens


I'm writing web application which should support both mouse and touch interactions. For testing I use touch screen device with Windows 7. I've tried to sniff touch events in latest Firefox and Chrome canary and got the following results:

On touch Firefox fires touch and corresponding mouse event. Chrome fires touchstart/mousedown, touchend/mouseup pairs, but mousemove fired in very strange manner: one/two times while touchmove.

All mouse events handled as always.

Is there any way to handle mouse and touch evens simultaneously on modern touch screens? If Firefox fires a pair of touch and mouse event what happens on touchmove with mousemove in Chrome? Should I translate all mouse events to touch or vice versa? I hope to find right way to create responsive interface.


Solution

  • You should rather check availability of touch interface and bind events according to that.

    You can do something like this:

    (function () {
        if ('ontouchstart' in window) {
            window.Evt = {
                PUSH : 'touchstart',
                MOVE : 'touchmove',
                RELEASE : 'touchend'
            };
        } else {
            window.Evt = {
                PUSH : 'mousedown',
                MOVE : 'mousemove',
                RELEASE : 'mouseup'
            };
        }
    }());
    
    // and then...
    
    document.getElementById('mydiv').addEventListener(Evt.PUSH, myStartDragHandler, false);
    


    If you want to handle both in same time and browser does not translate well touch events into mouse events, you can catch touch events and stop them - then corresponding mouse event shouldn't be fired by browser (you won't have double events) and you can fire it yourself as mouse event or just handle it.

    var mydiv = document.getElementsById('mydiv');
    mydiv.addEventListener('mousemove', myMoveHandler, false);
    mydiv.addEventListener('touchmove', function (e) {
        // stop touch event
        e.stopPropagation();
        e.preventDefault();
    
        // translate to mouse event
        var clkEvt = document.createEvent('MouseEvent');
        clkEvt.initMouseEvent('mousemove', true, true, window, e.detail, 
                     e.touches[0].screenX, e.touches[0].screenY, 
                     e.touches[0].clientX, e.touches[0].clientY, 
                     false, false, false, false, 
                     0, null);
        mydiv.dispatchEvent(clkEvt);
    
        // or just handle touch event
        myMoveHandler(e);
    }, false);