なぜ「の(){}」ステートメントの最後の要素ではなく、それ自体に意味コレクション内の各要素にイベントを追加することはできません
-
25-09-2019 - |
質問
Window
の負荷では、DD
内部のすべてのQuote_App
要素はonCLick
イベントがトリガ機能Lorem
が、しかし、Lorem
はむしろ機能をtrigged素子よりもnodeName
文で最後の要素のId
とFor
を返すことを追加している必要があります。私はLorem
機能をトリガー要素のnodeName
とId
を返すようにしたいでしょう。
function Lorem(Control){
/* this.Control=Control; */
this.Amet=function(){
return Control.nodeName+"\n"+Control.id;
};
};
function Event(Mode,Function,Event,Element,Capture_or_Bubble){
if(Mode.toLowerCase()!="remove"){
if(Element.addEventListener){
if(!Capture_or_Bubble){
Capture_or_Bubble=false;
}else{
if(Capture_or_Bubble.toLowerCase()!="true"){
Capture_or_Bubble=false;
}else{
Capture_or_Bubble=true;
};
};
Element.addEventListener(Event,Function,Capture_or_Bubble);
}else{
Element.attachEvent("on"+Event,Function);
};
};
};
function Controls(){
var Controls=document.getElementById("Quote_App").getElementsByTagName("dd");
for(var i=0;i<Controls.length;i++){
var Control=Controls[i];
Event("add",function(){
var lorem=new Lorem(Control);
lorem.Control=Control;
alert(lorem.Amet());
},"click",Controls[i]);
};
};
Event("add",Controls,"load",window);
現在、あなたは常に最後DD
要素のLorem
とnodeName
を返す任意のId
要素DD
をクリックします。
Lorem
トリガnodeName
ことId
(Control
)のControl[i]
とLorem
を返す必要があります。
私はこれが起こることについてに行くにはどうすればよい?
ありがとうございます!
解決
あなたは各ループの反復でi
の値をキャプチャするためにイベントハンドラをアタッチしているループ内でクロージャを必要としています。
for(var i=0;i<Controls.length;i++) {
(function() {
var Control=Controls[i];
Event("add",function(){
var lorem=new Lorem(Control);
lorem.Control=Control;
alert(lorem.Amet());
},"click",Controls[i]);
})();
};
ここで私には、JavaScriptの良い友人、自己呼び出す無名関数を使用して上記の閉鎖を作成しました。
閉鎖が必要な理由は、それなしで、任意のイベントハンドラ関数が実行された時点でi
の値は、我々が望むものを、最後のループ反復でi
の値ではないだろうということです。それは、各ループ反復であると私たちは、このように私たちは、各反復で、この値をキャプチャする必要が、我々はそれぞれのイベントハンドラ関数を宣言した時点で、i
の値を求めています。匿名関数を使用すると、すぐにそれが宣言だとして実行が所望の値を取得するための優れたメカニズムであること。
もう一つのポイントは、それはあなたを助けることが少しオフトピックしかし、そのイベントのキャプチャはすべてのブラウザでサポートされていません(のエヘンの、IE)が、イベントバブリングがあります。これは、効果的にクロスブラウザのWebアプリケーションを開発するためのuseCapture
でaddEventListener
ブールフラグがかなり無用になります。私はそのためにそれを使用しないようお勧めする。
もう一つは、JavaScriptは一般的に、関数名や変数名にキャメルケースを使用しています。パスカルケーシングは一般のみコンストラクタ関数(オブジェクトを作成する機能)のために使用されます。
他のヒント
、これらの文献は、この関数を呼び出す時に解決されます。
あなたのケースでは、
var functions = [];
function outer() {
for (var i = 0; i < N; i++) { // <------------
functions[i] = function() { // |
alert(i); // <-- this 'i' refers to this one
}
} // At the end of the for loop, i == N (or N+1?)
}
functions[x](); // Will show N (or N+1)
// because that's the current value of i in the outer function
// (which is kept alive just because something refers to it)
あなたがやりたいことは例えば、後の評価のために、ループの各段階で「I」の値をキャプチャです:ます。
var functions = [];
function outer() {
for (var i = 0; i < N; i++) { // <---------------------------------------
functions[i] = (function(my_i) { // <---- |
return function () { // | |
alert(my_i); // my_i refers to this which is a copy of 'i' there
}
}(i)); // run function(with my_i = the i at each step of the loop)
}
}
functions[x](); // Will show x
あなたは、パラメータとして、現在のカウンタのコピーを取得し、内部関数があります見ることができます。そのコピーで生きているこの内部機能の滞在、それを作成した機能のmy_iの保存された関数が返すinnest値への以降の呼び出しそう - クリア? : - )
このクロージャの素晴らしい世界です。そう行くと死ぬまで「JavaScriptのクロージャを」グーグル、それは心曲げまずそれを得るためのビットを取るかもしれないが、その後、あなたは喜んでいるよ!
このはラスカムの答えのより明白な変異体であってもよい。
function Controls() {
var Controls = document.getElementById("Quote_App").getElementsByTagName("dd");
var createHandlerFor = function(CurrentControl) {
return function() {
var lorem=new Lorem(CurrentControl);
lorem.Control=CurrentControl;
alert(lorem.Amet());
}
};
for (var i=0; i<Controls.length; i++) {
Event("add", createHandlerFor(Controls[i]), "click", Controls[i]);
}
};