在Passing 'this' and argument to addEventListener function without using bind的讨论中,提到了缓存功能。
例如,考虑以下事件监听器:
window.addEventListener('event1', callback1, false);
window.addEventListener('event2', callback2, false);
window.addEventListener('event3', callback3, false);
window.addEventListener('event4', callback4, false);
window.addEventListener('event5', callback5, false);
是否可以缓存它们的删除(例如在数组中)?
var unloaders = []; // Keeps track of unloader functions
unloaders.push(window.removeEventListener('event1', callback1, false));
unloaders.push(window.removeEventListener('event2', callback2, false));
unloaders.push(window.removeEventListener('event3', callback3, false));
unloaders.push(window.removeEventListener('event4', callback4, false));
unloaders.push(window.removeEventListener('event5', callback5, false));
最后,如果可以缓存它们,它们如何在正确的时间执行?
for (let i = 0, len = unloaders.length; i < len; i++) {
//
}
答案 0 :(得分:1)
unloaders.push(window.removeEventListener('event1', callback1, false))
不会将函数放在数组中以便稍后执行,而是执行函数并将结果值放入数组中,即不是你想要的。
来自另一个问题的unload
实际上会构造一个匿名闭包函数并将其放入数组中,因此简化了:
var unloaders = []; // Keeps track of unloader functions
unloaders.push(function() {
window.removeEventListener('event2', callback2, false);
});
这有点类似于绑定函数并将绑定函数放入数组中,因此以下结果会产生相同的结果:
// This just binds the function, effectively creating a new function,
// but does not execute it (yet)
var bound = window.removeEventListener.bind(window, 'event2', callback2, false);
unloaders.push(bound);
我更喜欢第一种风格,但两者都没关系,实际上没有一个闭包但是绑定函数可能会避免一些问题,在这种情况下,闭包关闭过多的东西,保持它人为活着。但这通常是罕见的。
无论如何最终调用存储在数组中的函数,你只需要迭代它然后一个接一个地调用函数。
for (let i = 0, len = unloaders.length; i < len; i++) {
unloaders[i]();
}
但是,为了避免异常提前退出循环,我建议你将调用包装在try-catch中。
for (let i = 0, len = unloaders.length; i < len; i++) {
try {
unloaders[i]();
}
catch (ex) {
// Do something
}
}
实际上,最好以相反的顺序调用卸载程序(后进先出)。
for (let i = unloaders.length - 1; i >= 0; i--) {
try {
unloaders[i]();
}
catch (ex) {
// Do something
}
}
其他问题中的unload
函数中还有一些 magic :它返回一个函数,让您可以随时调用刚刚注册的卸载程序,并将其从这样做时unloaders
数组。这对我也提供的unloadWindow
函数很重要。