[英]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()
按该顺序执行所有操作:
执行给定事件类型的所有处理程序和附加到匹配元素的行为。
因此,
第一次调用test
,您添加了一个completeStatus = 0
的事件侦听器,并触发了它。 所以你得到
0
第二次调用test
,前一个事件侦听器的completeStatus = 1
。 然后,添加另一个具有completeStatus = 0
事件侦听器,并同时触发两者。 所以你得到
1 // From the first event listener 0 // From the second event listener
第三次调用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.