我们发现,在最近升级到Google Chrome(版本55+)时,pointer events引入了{em>"并采用了更新标准来统一两种模式:指针事件。" ,我们需要修改我们如何处理事件以向后兼容。我们的应用程序专门针对Chrome。
我们今天早上已经experimenting,试图弄清楚哪个事件已被解雇(基于Chrome版本),因此我们可以为所有应用程序的用户正确处理该事件。作为测试,我写了以下内容:
$(document).on('mousedown touchstart pointerdown', '.foo', function(event){
console.log( event.type + ": " + event.which );
switch(event.type) {
case 'mousedown':
console.log('moused!');
break;
case 'touchstart':
console.log('touched!');
break;
case 'pointerdown':
console.log('pointed');
break;
};
})
在非移动设备中,mousedown
和pointerdown
都已注册。在移动设备中,所有三个事件都会向控制台吐出。
澄清:在遇到和处理第一个事件后,不需要触发任何其他事件。换句话说,如果pointerdown
触发,那么我需要阻止mousedown
和touchstart
触发。后续点击也应该有效,所以如果我得到pointerdown
并再次点击,我应该得到另一个pointerdown
(或任何适合浏览器版本或设备的事件)。
我预计break;
会导致jQuery离开switch()
,但这并不会发生。所以我在每个案例中添加了.clearQueue()
:
$(this).clearQueue();
再次,我预计会遇到并处理该事件,队列将被清除,我不会触发任何其他事件。
我错了。
我开始觉得我错过了一些明显的东西,但我无法用手指指着它。我已尝试.stop()
,.finish()
以及这些函数的组合,以拦截所需的一个函数(基于浏览器版本)并清除队列,以便其余部分不会触发。
我以为我很了解JavaScript事件队列,但显然我也错了。
我错过了一些明显的东西吗?如果是这样,它是什么?
答案 0 :(得分:3)
我认为.stop()
和.finish()
与使用动画队列有关,而与事件队列无关,.clearQueue()
与事件队列无关:
在没有参数的情况下使用时,.clearQueue()会删除剩余的参数 来自fx的函数,标准效果队列。就是这样 类似于.stop(true)。但是,虽然.stop()方法是有意义的 仅用于动画,.clearQueue()也可用于 删除任何已添加到通用jQuery队列的函数 .queue()方法。
但是,如果你已经处理了一个事件并希望阻止其他人被引发,你可以在一个闭包中实现你自己的handled
标志作为解决方法:
以下是一个示例(可执行版 here ):
// These free variables will be shared in the various callback functions below
var handled = false;
var eventType = null;
$(document).on('mousedown touchstart pointerdown', '.foo', function(event){
// If the current event hasn't been handled or if the current
// has been handled but the event is the same as the previous fired
// event, proceed:
if(!handled || (handled && event.type === eventType)){
// None of the events have been handled yet.
// Determine which has fired and act appropriately:
// Register the current event for comparison later
eventType = event.type;
console.log( eventType + ": " + event.which );
switch(eventType) {
case 'mousedown':
console.log('moused!');
break;
case 'touchstart':
console.log('touched!');
break;
case 'pointerdown':
console.log('pointed');
break;
};
// Flag that one of the events registered earlier has been handled
handled = true;
} else {
// One of the earlier registered events has already been handled
// Prevent the event from performing its native function
// (i.e. cancel the event)
event.preventDefault();
// Don't allow the event to propagate
event.stopPropagation();
}
});
答案 1 :(得分:0)
最后你可以return false
,只有第一种支持的类型(和第一次被解雇)才能被任何系统捕获。
break
工作正常,但它不会影响这个问题,因为这些是不同的事件,因此触发处理程序的次数与事件触发的次数相同。
$(document).on('mousedown touchstart pointerdown', '.foo', function(event){
console.log( event.type + ": " + event.which );
switch(event.type) {
case 'mousedown':
console.log('moused!');
break;
case 'touchstart':
console.log('touched!');
break;
case 'pointerdown':
console.log('pointed');
break;
};
// added the following line which forces any subsequent events for the same action and also stop the event from bubbling up the dom
return false;
})

.foo{
padding:50px;
margin:10px;
border:5px double #ccc;
text-align:center;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="foo">.foo box for clicking</div>
&#13;