我有一个函数中的事件监听器。监听器和发射器都具有相同的功能。
当事件触发时,变量会递增。到现在为止还挺好。但是当我多次调用该函数时,在同一函数调用中会多次触发侦听器。
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来试用它。
答案 0 :(得分:2)
.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
答案 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();
但是性能影响呢?使用这种方法有没有优势/劣势?