我有一个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。