2013-06-30 33 views
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(...); 

我可以删除它,如果使用一个变量函数来代替,但我需要通过一些参数回调,所以我需要使用匿名函数。

+0

IIRC,'cloneNode'克隆了一切,但事件监听器。在'document'范围内做这件事可能很搞笑,但.. – fjdumont

+1

一种方法是将整个事件绑定到一个自定义函数中。然后该函数可以保持对传入处理程序的引用,并确保只绑定一个处理程序。当然,这要求处理程序仅通过该函数绑定到元素。 –

+1

我不明白你的解释为什么你必须使用匿名函数。这里是一个相关的问题btw:http://stackoverflow.com/questions/4386300/javascript-dom-how-to-remove-all-events-of-a-dom-object – basilikum

回答

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"); 
+0

试过了,但它被调用两次。也许我做错了 - Fiddler Link http://jsfiddle.net/NeT7W/1/ – GoodSp33d

+1

@ 2-Stroker:修正了代码,它必须是'element.removeEventListener(evtName,handlers [evtName])''。 –

0

商店的地方,你已经应用了听众,只有添加它,如果它没有已经添加。

+0

可以使用这个,但在我的情况下,唯一的持久性变量将是在Web Sql数据库中。 – GoodSp33d

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/

API可以通过返回.set(callback).remove()功能的对象,而不是使用一个单一的功能做改善这两件事,如果你喜欢。

相关问题