清除JavaScript / jQuery事件队列

时间:2016-12-20 17:18:34

标签: javascript jquery google-chrome javascript-events

我们发现,在最近升级到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;    
    };
})

在非移动设备中,mousedownpointerdown都已注册。在移动设备中,所有三个事件都会向控制台吐出。

澄清:在遇到和处理第一个事件后,不需要触发任何其他事件。换句话说,如果pointerdown触发,那么我需要阻止mousedowntouchstart触发。后续点击也应该有效,所以如果我得到pointerdown并再次点击,我应该得到另一个pointerdown(或任何适合浏览器版本或设备的事件)。

我预计break;会导致jQuery离开switch(),但这并不会发生。所以我在每个案例中添加了.clearQueue()

$(this).clearQueue();

再次,我预计会遇到并处理该事件,队列将被清除,我不会触发任何其他事件。

我错了。

我开始觉得我错过了一些明显的东西,但我无法用手指指着它。我已尝试.stop().finish()以及这些函数的组合,以拦截所需的一个函数(基于浏览器版本)并清除队列,以便其余部分不会触发。

我以为我很了解JavaScript事件队列,但显然我也错了。

我错过了一些明显的东西吗?如果是这样,它是什么?

2 个答案:

答案 0 :(得分:3)

我认为.stop().finish()与使用动画队列有关,而与事件队列无关,.clearQueue()与事件队列无关:

JQuery documentation说:

  

在没有参数的情况下使用时,.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;
&#13;
&#13;