繁体   English   中英

封装在函数中的JavaScript事件监听器

[英]JavaScript Event Listener encapsulated in a function

我有一个函数中的事件侦听器。 侦听器和发射器都处于同一功能中。

事件触发时,变量将递增。 到现在为止还挺好。 但是,当我多次调用该函数时,在同一函数调用中多次触发了侦听器。

var test = function() {    
    var completeStatus = 0;

    $(document).on('gt', function() {
        console.log(++completeStatus);
    });
    $(document).trigger('gt');
}

test();
test();
test();

由于该函数被调用了三遍,因此它期望它输出三遍。 但它输出:0 1 0 2 1

为什么会这样以及如何获得所需的行为?

这是一个jsfiddle来尝试。

.on()添加事件列表器,它不会替代以前的列表器:

将一个或多个事件的事件处理函数附加到所选元素。

当一个元素具有多个事件侦听器时,顺序是明确定义的:

绑定到元素的事件处理程序的调用顺序与其绑定的顺序相同。

.trigger()按该顺序执行所有操作:

执行给定事件类型的所有处理程序和附加到匹配元素的行为。

因此,

  1. 第一次调用test ,您添加了一个completeStatus = 0的事件侦听器,并触发了它。 所以你得到

     0 
  2. 第二次调用test ,前一个事件侦听器的completeStatus = 1 然后,添加另一个具有completeStatus = 0事件侦听器,并同时触发两者。 所以你得到

     1 // From the first event listener 0 // From the second event listener 
  3. 第三次调用test ,第一个事件侦听器具有completeStatus = 2 ,第二个事件侦听器具有completeStatus = 1 然后,添加带有completeStatus = 0的第三个事件侦听器,并全部触发它们。 所以你得到

     2 // From the first event listener 1 // From the second event listener 0 // From the third event listener 

因为您正在使用$(document).trigger('gt'); 因此,它在所有文档事件中都启动了触发事件,这就是为什么增加函数返回输出的调用

0       //from first function call
1 0     //from second function call 
2 1 0   //frm third function call
.... and so on

解决方案:

var test = function() {    
    var completeStatus = 0;
    var pageInitialized = false;    
    $(document).on('gt', function() {
        if(pageInitialized) return;
        console.log(++completeStatus);
        pageInitialized = true;
    });
    $(document).trigger('gt');
}

test();
test();
test();

如上面的答复所述, .on()添加了事件侦听器,因此在您的示例中,它添加了3次。

除了较早的答案外,最好避免添加多个侦听器,否则,如果无法删除它们,可能会导致内存泄漏。 因此,您可以尝试此解决方案,该解决方案在再次添加之前删除事件侦听器。

var test = function() {    
   var completeStatus = 0;
   var GT_EVT = 'gt';

   $(document).off(GT_EVT).on(GT_EVT, function() {
      console.log(++completeStatus);
   });

   $(document).trigger(GT_EVT);

}

另一种方法是每次执行函数时生成唯一的事件和处理程序:

var test = function() {    
    var completeStatus = 0;
    var uniqid = Math.random().toString(36).slice(-8);

    $(document).on('gt' + uniqid, function() {
        console.log(++completeStatus);
    });
    $(document).trigger('gt' + uniqid);
}

test();
test();
test();

小提琴

但是对性能的影响呢? 使用这种方法是否有优点/缺点?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM