一連のオーディオファイルに含まれるいくつかのストーリーを聞くためのJavaScriptが付いたページがあります。私はポップコーンライブラリを使用して、脚注を特定のタイムスタンプに追加し、音声が再生されるときにページ上のテキスト内の単語をハイライト表示します。私は多くのオーディオ要素と多くのポップコーンのインスタンスを含むjavascriptオブジェクトAudioPlayer(この例ではインスタンスはpと呼ばれます)を持っています。最初にオーディオ要素に '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();
}
しかし、私はaudio要素が再ロードされます場合は、「stampX」は、より再び呼び出さなっていることを、このコードをテストで見つかった:私は与えられたアイテムのタイムスタンプを取得するときにそのため、私は実行するには、このようにコールバックコードを書きましたので、私の唯一の結論は、removeEventListenerが何らかの形で、以下のaddEventListenerと同じ参照を取得していないということです。
私はこれをデバッグするのが難しいと思っています。私は、イベントリスナー(関数呼び出しではない)の関数参照が必要なので、変数をstampXに渡すことはできません。
とにかく、これを書くための適切な方法を見つけるのが難しいです。私は、最初にstampXが呼び出されたときにeventListenerを削除できるようにしています。