在触摸屏上处理鼠标和触摸事件

joh*_*nny 12 javascript firefox google-chrome touchscreen touch

我正在编写应该支持鼠标和触摸交互的Web应用程序.为了测试,我使用Windows 7的触摸屏设备.我试图在最新的Firefox和Chrome金丝雀中嗅探触摸事件,并得到以下结果:

触摸Firefox触发触摸和相应的鼠标事件.Chrome发射touchstart/mousedown,touchend/mouseup成对,但mousemove以非常奇怪的方式发射:一次/两次touchmove.

所有鼠标事件一如既往地处理.

有没有办法在现代触摸屏上同时处理鼠标和触控平板?如果Firefox触发一个对触摸和鼠标活动的想法上发生的touchmovemousemoveChrome浏览器?我应该翻译所有鼠标事件,反之亦然?我希望找到创建响应式界面的正确方法.

Ric*_*ers 16

您无法事先预测要监听哪些事件(例如,您知道在页面加载后可能会插入USB触摸屏).

相反,您应该始终同时监听触摸事件和鼠标事件,但是对您处理的触摸事件调用preventDefault()以防止(现在是多余的)鼠标事件被触发.有关详细信息,请访问http://www.html5rocks.com/en/mobile/touchandmouse/.


lup*_*tus 7

您应该检查触摸界面的可用性并根据它来绑定事件.

你可以这样做:

(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);
Run Code Online (Sandbox Code Playgroud)


如果你想同时处理这两个并且浏览器没有将触摸事件很好地转换为鼠标事件,你可以捕获触摸事件并停止它们 - 然后浏览器不应该触发相应的鼠标事件(你不会有双重事件)你可以自己发射它作为鼠标事件或只​​是处理它.

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);
Run Code Online (Sandbox Code Playgroud)

  • 不幸的是,这种方法在Firefox中不起作用.即使你在触摸事件上调用`preventDefault`和`stopPropagation`,这个浏览器也会发送鼠标事件...到目前为止我找到的解决方法是忽略了`mousedown`事件,它在与之前的`touchstart相同的位置启动时`event并忽略`mousemove`和`mouseup`,没有先前的'mousedown`.很糟糕,其他浏览器不支持Microsofts Pointer API.使用这个简单的触摸API更容易... (2认同)

小智 7

这个线程上的解决方案已经过时了 - 对于那些在 2021 年仍然登陆这里的人(像我一样),有一个新的指针事件 W3 规范。这些事件将鼠标和触摸合二为一。

https://developer.mozilla.org/en-US/docs/Web/API/Pointer_events

https://www.w3.org/TR/pointerevents/