У меня есть страница с некоторым javascript для прослушивания некоторых рассказов, которые находятся в серии аудиофайлов. Я использую библиотеку попкорна для добавления примечаний к конкретным временным меткам, которые выделяют слова в тексте на странице при воспроизведении звука. У меня есть объект javascript AudioPlayer (экземпляр в этом примере называется ap), который содержит много аудио-элементов и множество экземпляров попкорна. В первый раз, когда аудио-элемент имеет «загруженные метаданные», если у меня есть метки времени для этого элемента, я хочу создать сноски попкорна. Но я не хочу запускать эту функцию более одного раза для данного аудио-элемента. То есть люди могут нажать на элемент и перезагрузить его, но я не хочу воссоздавать временные метки. По этой причине, я написал обратного вызова код, как это работать, когда я получаю временные метки для данного элемента:как удалить прослушиватель событий из этого во время обратного вызова
// 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.
Я нахожу это трудным для отладки. Я не могу передать переменную в штампX, потому что вам нужна ссылка на функцию для прослушивателя событий (а не вызов функции).
Во всяком случае, мне трудно найти правильный способ написать это, чтобы я мог удалить eventListener при первом вызове штампаX.