2012-04-02 23 views
0

私はJavascriptを少し新しくしています。私の機能で何が起こっているのか正確には分かりません。関数で動的にjavascriptイベントハンドラを定義する方法

背景:私のスクリプトでは、要素に「toggler」または「toggled」のいずれかのクラスを割り当てて自動的にリンクさせるようになっているので、トグルをチェック/非チェックすると、

スクリプトはpageloadで実行され、クラス "toggler"を持つ要素を検索し、それに応じてonclickハンドラを割り当てます。

function makeToggle() { 
    for (i=0;i<toggler.length;i++) { 
     toggler[i].onclick=function(){toggleSection(this,i)}; 
    } 
    } 

    function toggleSection(obj,index) { 
    if (obj.checked==true) { 
     toggled[index].style.display="inline-block"; 
    } else { 
     toggled[index].style.display="none"; 
    } 
    } 

「これは」正しく渡され、それが適用されますどのようなチェックボックスに解決されますが、「インデックス」が常に代わりのトグラー配列の長さに設定されている。ここでは、コードのビットは、私が持つ問題を抱えているのです増分される。例えば、第一および第二のtogglers' onclickのは次のようになります。

onclick="toggleSection(this,0)" 
onclick="toggleSection(this,1)" 

それらが実際に(私は5つの要素がトグラーのように定義していると仮定した場合)に設定されているどのようなものです:私は何から

onclick="toggleSection(this,5)" 
onclick="toggleSection(this,5)" 

」あなたが関数を作成している間、あなたは私にそのようなをその変数を使用することはできません、私はそれがスコープの問題、または、私は関数を呼び出すだ方法だと思うが、私が見つけたものは何も

+0

すべての答えは非常に有用でした。 jbabey'sは受け入れられた答えです。なぜなら、実際に何が起こっているのかを説明することで、もう少し深みが増すからです。閉鎖を理解するのに役立つ素晴らしいリンク – ctshiner

答えて

0

function makeToggle() { 
    for (i=0;i<toggler.length;i++) { 
     toggler[i].addEventListener("click", (function(d) { return function(){ 
        toggleSection(this,d); 
     }; })(i), true); 
    } 
} 

か、あなたのスタイルでは、このようにしてみてくださいthis blog postに詳細が記載されています。

この理由は非常に複雑です。イベントハンドラとして定義する無名関数はforループではなくattachEventsToListItemsのスコープから変数iを継承します。しかし、イベントハンドラが実行される時点で、forループはその反復を完了し、この関数のiの値は4になります。ここでの問題は、イベントハンドラとして定義した関数は新しいスコープを作成しないことです彼らが処刑されるまでは私のために。

問題を修正するには、閉鎖を必要とする:

for (i=0;i<toggler.length;i++) { 
    toggler[i].onclick= (function (index) { 
     return function() { 
      toggleSection(this,index); 
     }; 
    }) (i); 
} 

あなたはここに俳優でそれを見ることができます:http://jsfiddle.net/Vb2t2/

+0

うわー、ありがとう。非常に有用な答え。そのリンクjbabeyが私に与えたリンクは、正しい方向に、学習に賢明を向けるのを助けました。再度、感謝します! – ctshiner

+0

@ctshinerあなたはあなたの問題を解決する答えを受け入れるべきです;) – jbabey

1

あまり意味がありません読みまし。あなたがそうするなら、の値がの場合、最後の値はです。です。あなたの問題では私は常にトグルの長さになります。あなたのonclick関数へのparamaterとして

ので、あなたが変数を渡す必要があります(私は)、

はあなたが

function makeToggle() { 
    for (i=0;i<toggler.length;i++) { 
     toggler[i].onclick = (function(d) { return function(){toggleSection(this,d)}})(i); 
    } 
} 
+1

ocanalが書いたものが正しい。私はdiffessenceを示すためにjsFiddleの例を作成しました。 http://jsfiddle.net/5K2a4/1/ – freakish

関連する問題