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();
函数被调用了3次,期望输出3次1。但它输出:
0
1个
0
2个
1
这是为什么以及如何获得所需的行为?
这里有一个 jsfiddle 来试试看。
.on()
添加事件列表,它不会替换以前的:
Attach an event handler function for one or more events to the
selected elements.
当一个元素有多个事件监听器时,顺序是明确的:
Event handlers bound to an element are called in the same order that
they were bound.
并且.trigger()
按顺序执行它们:
Execute all handlers and behaviors attached to the matched elements
for the given event type.
因此,
第一次调用 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();
但是对性能的影响呢?有没有advantage/disadvantage使用这种方法的?
我有一个函数中的事件侦听器。侦听器和发射器都在同一个函数中。
事件触发时,变量会递增。到目前为止,一切都很好。但是当我多次调用该函数时,在同一个函数调用中多次触发监听器。
var test = function() {
var completeStatus = 0;
$(document).on('gt', function() {
console.log(++completeStatus);
});
$(document).trigger('gt');
}
test();
test();
test();
函数被调用了3次,期望输出3次1。但它输出: 0 1个 0 2个 1
这是为什么以及如何获得所需的行为?
这里有一个 jsfiddle 来试试看。
.on()
添加事件列表,它不会替换以前的:
Attach an event handler function for one or more events to the selected elements.
当一个元素有多个事件监听器时,顺序是明确的:
Event handlers bound to an element are called in the same order that they were bound.
并且.trigger()
按顺序执行它们:
Execute all handlers and behaviors attached to the matched elements for the given event type.
因此,
第一次调用
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();
但是对性能的影响呢?有没有advantage/disadvantage使用这种方法的?