清除JavaScript/jQuery事件队列
我们发现,在最近对Google Chrome(55+版)的升级过程中,“引入了一个统一两种模型的新标准:指针事件”。我们需要修改处理事件的方式,使其向后兼容。我们的应用程序是专门为Chrome编写的 今天上午,我们一直在尝试找出触发了哪一个事件(基于Chrome版本),以便我们能够为应用程序的所有用户适当地处理该事件。作为测试,我写了以下内容:清除JavaScript/jQuery事件队列,javascript,jquery,google-chrome,jquery-events,Javascript,Jquery,Google Chrome,Jquery Events,我们发现,在最近对Google Chrome(55+版)的升级过程中,“引入了一个统一两种模型的新标准:指针事件”。我们需要修改处理事件的方式,使其向后兼容。我们的应用程序是专门为Chrome编写的 今天上午,我们一直在尝试找出触发了哪一个事件(基于Chrome版本),以便我们能够为应用程序的所有用户适当地处理该事件。作为测试,我写了以下内容: $(document).on('mousedown touchstart pointerdown', '.foo', function(event){
$(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
和touchtstart
触发。随后的单击也会起作用,因此如果我得到一个pointerdown
并再次单击,我会得到另一个pointerdown
(或任何适合浏览器版本或设备的事件)
我期望中断
会导致jQuery离开开关(),但这不会发生。因此,我在每个案例中添加了:
$(this).clearQueue();
再一次,我希望会遇到并处理该事件,队列将被清除,并且不会触发任何其他事件
我错了
我开始觉得我错过了一些明显的东西,但我不能把我的手指放在上面。我已经尝试了,以及这些功能的组合,以便截获所需的一个功能(基于浏览器版本),并清除队列,使其余的不会触发
我认为我非常了解JavaScript事件队列,但显然我也错了
我错过了什么明显的东西吗?如果是,是什么 我认为.stop()
和.finish()
与动画队列相关,而不是与事件队列相关,.clearQueue()
也与事件队列无关:
报告说:
如果在没有参数的情况下使用,.clearQueue()将删除剩余的
来自标准效果队列fx的函数。就这样
类似于.stop(true)。但是,虽然.stop()方法的作用是
仅用于动画,.clearQueue()也可用于
使用删除已添加到通用jQuery队列的任何函数
.queue()方法
但是,如果您已经处理了一个事件,并且希望阻止其他事件被引发,您可以在闭包中实现自己的handled
标志,作为一种解决方法:
下面是一个示例(可执行版本):
您可以在最后
返回false
,任何系统都只捕获支持的第一种类型(以及第一次激发的类型)
中断
工作正常,但不会影响此问题,因为这些是不同的事件,因此触发处理程序的次数与触发事件的次数相同
$(document).on('mousedown touchstart pointerdown','.foo',函数(事件){
console.log(event.type+”:“+event.which);
开关(事件类型){
案例“mousedown”:
console.log('moused!');
打破
案例“touchstart”:
console.log('toucted!');
打破
案例“pointerdown”:
console.log('pointed');
打破
};
//添加了下面的一行,该行强制执行相同操作的任何后续事件,并阻止事件冒泡到dom中
返回false;
})
.foo{
填充:50px;
利润率:10px;
边框:5px双#ccc;
文本对齐:居中;
}
.foo框,用于单击
,根据您发布的内容,.clearQueue()
应该可以工作.stopPropagation()
不起作用。所有事件仍会触发,并且每个案例都会返回其值。这是我早些时候测试过的东西,我甚至试着在每个案例中放置.stopPropagation()
,在开关之前和开关之后<代码>clearQueue()
用于效果队列或自定义队列,而不是事件队列.stopPropagation()
将限制事件冒泡然后再次触发。“clearQueue()还可用于删除使用.queue()方法添加到通用jQuery队列中的任何函数。”也许jQuery不使用.queue()
添加到自己的队列中。JQuery抽象标准JavaScript和DOM API。当您使用queue()
时,您正在注册自己的回调,但对于事件注册。在(…..)
上,没有使用。queue()
。这很公平-这解释了.clearQueue()
无法工作的原因。这不会停止触发的其他事件。看:这说明了这一点return false
与使用event.preventDefault()
和event.stopPropagation()
相同,它们一次只截获一个事件。请参阅:了解我的解决方案及其与您的解决方案的区别。@ScottMarcus您正在测试不同类型的事件。OP请求为相同的用户操作触发事件,即mousedown
、touchstart
和pointerdown
。
// 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();
}
});