0

编辑:我需要调用一个获取数据并重新加载页面内容的函数。但是一旦另一个函数获取了数据(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(...);

如果改用变量函数,我可以删除它,但我需要将一些参数传递给回调,所以我需要使用匿名函数。

4

3 回答 3

2

使用菲利克斯的建议

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");
于 2013-06-30T14:33:41.703 回答
1

这是一种方法:

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,而不是使用单个函数来做这两件事。

于 2013-06-30T16:29:35.100 回答
0

存储您已经应用了侦听器的位置,如果尚未添加,则仅添加它。

于 2013-06-30T14:36:51.723 回答