编辑:我需要调用一个获取数据并重新加载页面内容的函数。但是,一旦另一个函数获取了数据(webSql),就必须调用它。我无法使用WebSql回调,因为变量超出范围。所以我创建了一个自定义事件并在第二个函数范围中添加了一个监听器。因此,当获取数据时,我将在第一个函数范围内调度该事件。现在问题是,如果页面被重新加载多次,监听器将被多次添加,并且所有将被调用,我不想要。
我需要确保只有一个函数正在侦听自定义事件。现在正在删除侦听器,如下所示:
document.addEventListener("customEvent", function () {
actualCallBack(var1, var2); // Since I need to pass parameters I need to use callBack within an anonymous function.
this.removeEventListener("customEvent", arguments.callee, false);
}, false);
但问题是匿名函数只有在首先调用它之后才会被删除。听众有可能多次加入。如何在添加新事件之前删除事件侦听器?
document.removeEventListener("customEvent");
document.addEventListener(...);
我可以删除它,如果使用变量函数,但我需要将一些参数传递给回调,所以我需要使用匿名函数。
答案 0 :(得分:2)
使用felix的建议
var setSingletonEventListener = (function(element){
var handlers = {};
return function(evtName, func){
handlers.hasOwnProperty(evtName) && element.removeEventListener(evtName, handlers[evtName]);
if (func) {
handlers[evtName] = func;
element.addEventListener(evtName, func);
} else {
delete handlers[evtName];
}
};
})(document);
setSingletonEventListener("custom event", function(){
});
//replaces the previous
setSingletonEventListener("custom event", function(){
});
//removes the listener, if any
setSingletonEventListener("custom event");
答案 1 :(得分:0)
存储已经应用了侦听器的某个地方,如果尚未添加,则只添加它。
答案 2 :(得分:0)
这是一种方式:
var singletonEventListenerFor = function (element, eventName) {
var callback = null;
element.addEventListener(eventName, function () {
callback && callback();
});
return function (set) {
callback = set;
};
};
测试:
var event = document.createEvent("Event");
event.initEvent("customEvent", true, true);
var listener = singletonEventListenerFor(document, "customEvent");
var counter = 0;
listener(function () {
console.log(++counter);
});
// counter === 1
document.dispatchEvent(event);
// Remove the listener
listener();
// This shouldn't increment counter.
document.dispatchEvent(event);
listener(function () {
console.log(++counter);
});
// counter === 2
document.dispatchEvent(event);
// counter === 3
document.dispatchEvent(event);
console.log('3 === ' + counter);
http://jsfiddle.net/Dogbert/2zUZT/
如果您愿意,可以通过返回具有.set(callback)
和.remove()
函数的对象而不是使用单个函数来执行这两项操作来改进API。