2013-06-30 32 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()功能的對象,而不是使用一個單一的功能做改善這兩件事,如果你喜歡。

相關問題