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

时间:2015-06-29 12:22:30

标签: javascript javascript-events

我有一个函数中的事件监听器。监听器和发射器都具有相同的功能。

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

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

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

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

它期望它输出1三次,因为函数被调用三次。但它输出: 0 1 0 2 1

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

此处有一个jsfiddle来试用它。

4 个答案:

答案 0 :(得分:2)

.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
    

答案 1 :(得分:2)

因为您使用的是$(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();

答案 2 :(得分:1)

如上所述,回复.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);

}

答案 3 :(得分:0)

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

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();

Fiddle

但是性能影响呢?使用这种方法有没有优势/劣势?