我有一個JavaScript頁面,用於監聽一系列音頻文件中的某些故事。我使用爆米花庫爲腳註添加特定的時間戳,在音頻播放時突出顯示頁面文本中的文字。我有一個JavaScript對象AudioPlayer(本例中的實例稱爲ap),其中包含許多音頻元素和許多爆米花實例。第一次音頻元素具有'loadedmetadata',如果我有該項目的時間戳,我想創建爆米花腳註。但是,我不想爲給定的音頻項目多次運行此功能。也就是說,人們可以點擊一個項目並重新加載它,但我不想重新創建時間戳。出於這個原因,我寫了這樣的回調代碼時,我得到了一個給定的項目時間戳來運行:如何在回調期間從此刪除事件監聽器
// try to load any timestamps for this file
this.loadTS = function(ann) {
var xhr = new XMLHttpRequest();
xhr.open("GET", window.location.protocol+"//"+
window.location.hostname+"/sitename/timestamps/"+
window.location.pathname.substring(
window.location.pathname.lastIndexOf('/')+1)+".json",
true);
xhr.onreadystatechange=function(){
if(xhr.readyState==4 && xhr.status==200){
console.log(xhr.responseText);
this.timestamps = JSON.parse(xhr.responseText);
for(var idx in this.timestamps){
var stampX = function(){
// this is an audio element, get it's index to
// do the stamping
var x = window.ap.audios.indexOf(this);
// need to remove this listner so it doesn't fire again!
this.removeEventListener('loadedmetadata',stampX); // <- fail :(
// window.ap.audios[x]
// .removeEventListener('loadedmetadata',stampX);
// ^^ this failed too :(:(
// stamp away!
window.ap.stampItem(window.ap.winIGTs[x],
window.ap.timestamps[x], window.ap.audios[x],
window.ap.popcorns[x]);
};
this.audios[idx].addEventListener('loadedmetadata', stampX);
if(ann)
this.textIGTs[idx].setAttribute("class","igt existstamps");
}
} else console.log(xhr.status);
}.bind(this);
xhr.send();
}
但我在測試這個代碼,「stampX」是越來越再次調用發現如果音頻元素被重新加載,所以我唯一的結論是,removeEventListener在某種程度上沒有得到與下面的addEventListener相同的引用。
我發現這很難調試。我無法將變量傳遞給stampX,因爲需要事件偵聽器的函數引用(不是函數調用)。
無論如何,我很難找到正確的方法來寫這個,這樣我可以在第一次調用stampX時刪除eventListener。