javascriptでイベントを循環的に追加する場合のクローズド問題解決
2192 ワード
これは経典の問題です.一時期純jsを書きませんでした.最近はいつも以前転んだ穴に落ちています.今回は半日かけて登りました.だから記録してください.
昨日jsコードを書きましたが、カスタムdivに登録したonclickイベントで発見された値は常にサイクルの最後の層の値です.
最初のコード:
読む視線を邪魔しないように、この問題に関係のないコードを直接切ってください.
ここで一つのdivをクリックしてalertが出るのは最後のサイクルの値です.この現象はすぐに思い出します.これは古典的なクローズド問題です.Oclickのイベントを実行する時に外部関数にアラー[i]の定義を探します.ここでiはforサイクルを実行した後、array[array.length-1]になりました.
インターネットで検索してみましたが、改善の方法はたくさんあります.
方法1は、外層が匿名関数を包含し、各循環のインデックス結果を入力として入力し、自己実行する.
方法2は、同様にクローズドを利用して、innerTextに値を付ける部分は問題ありません.問題があるのはクローズド特性を使ったオンリーイベントの登録部分だけです.
方法3は、上記の解決方法は難しそうですが、クローズドの中でうろうろしています.個人的には、クローズドしなくてもいいと思います.他の解法を以下に示します.
昨日jsコードを書きましたが、カスタムdivに登録したonclickイベントで発見された値は常にサイクルの最後の層の値です.
最初のコード:
for(var i in array){
var rowDiv = document.createElement("div");
rowDiv.innerText = array[i]["name"];
rowDiv.onclick = function(){//
pNode = this.parentNode;
pNode.previousSibling.value = this.innerText;// div
if(onclickCallback){//
onclickCallback(array[i]);
}
};
}
読む視線を邪魔しないように、この問題に関係のないコードを直接切ってください.
for(var i in array){
var rowDiv = document.createElement("div");
rowDiv.innerText =array[i];
rowDiv.onclick = function(){//
alert(array[i]);
};
}
ここで一つのdivをクリックしてalertが出るのは最後のサイクルの値です.この現象はすぐに思い出します.これは古典的なクローズド問題です.Oclickのイベントを実行する時に外部関数にアラー[i]の定義を探します.ここでiはforサイクルを実行した後、array[array.length-1]になりました.
インターネットで検索してみましたが、改善の方法はたくさんあります.
方法1は、外層が匿名関数を包含し、各循環のインデックス結果を入力として入力し、自己実行する.
for(var i in array){
(function(obj){
var rowDiv = document.createElement("div");
rowDiv.innerText = obj;
rowDiv.onclick = function(){//
alert(obj);
};
})(array[i]);
}
方法2は、同様にクローズドを利用して、innerTextに値を付ける部分は問題ありません.問題があるのはクローズド特性を使ったオンリーイベントの登録部分だけです.
for(var i in array){
var rowDiv = document.createElement("div");
rowDiv.innerText = array[i];
rowDiv.onclick = (function(obj){//
return function(){
alert(obj);
};
})(array[i]);
}
方法3は、上記の解決方法は難しそうですが、クローズドの中でうろうろしています.個人的には、クローズドしなくてもいいと思います.他の解法を以下に示します.
for(var i in array){
var rowDiv = document.createElement("div");
rowDiv.innerText = array[i];
rowDiv.obj = array[i];
rowDiv.onclick = function(){//
alert(this.obj);
};
}
これは個人的には良いと思いますが、domオブジェクトにカスタム属性を追加して値を保存します.divのイベントがトリガされた時にはthisで参照できます.