2016-10-19 4 views
1

以下の動作はわかりません。ループ内のカウンタを変数に代入しても、現在の値は保持されません。

私は次の操作を行うには、以下のスクリプトを期待しています:

  1. すると、ユーザーがクリック
  2. のonclickイベントを割り当て、ボタンで各要素については、クラス「ボタン」
  3. を持つすべての要素を取得しますボタンをクリックすると、onclickが割り当てられたときの現在の値がiのアラートが表示されます。

「ボタン1」をクリックすると、「私はボタン1です」という警告が表示されます。

代わりに、3つのボタンすべてが「私はボタン3です」と警告します。 iカウンタの値が保持されていないようです。

<!DOCTYPE html> 
<html> 
    <head> 
     <meta charset="utf-8" /> 
     <title>Test</title> 
    </head> 
    <body> 
     <p class="button">Button 0</p> 
     <p class="button">Button 1</p> 
     <p class="button">Button 2</p> 
     <script> 
      var buttons = document.getElementsByClassName('button'); 
      for (var i=0 ; i < buttons.length ; i++){ 
       buttons[i].onclick = function(){ 
        alert("I am button " + i); 
       }; 
      } 

     </script> 
    </body> 
</html> 

どうしてですか?どのようにして目的の動作を達成できますか?

+0

あなたは閉鎖を形成する必要があります! –

+0

@ClydeLoboその質問は*します*私の質問に答えますが、この質問をする前に私はクロージャを探すことさえ考えなかったでしょう。 – Scribblemacher

答えて

2

これを試してください。それはClosuresと呼ばれます。変数iをキャプチャし、iがループの後で削除されないため、現在の値がiのイベントハンドラを呼び出します。したがって、あなたは関数を実行することによって得ることができるローカル変数が必要です。だから私は関数を作成し、変数iを彼に渡し、関数のスコープには、関数に対してローカルの変数paramがあります。これは新しい繰り返しです。

<!DOCTYPE html> 
 
<html> 
 
    <head> 
 
     <meta charset="utf-8" /> 
 
     <title>Test</title> 
 
    </head> 
 
    <body> 
 
     <p class="button">Button 0</p> 
 
     <p class="button">Button 1</p> 
 
     <p class="button">Button 2</p> 
 
     <script> 
 
      var buttons = document.getElementsByClassName('button'); 
 
      for (var i=0 ; i < buttons.length ; i++){ 
 
       buttons[i].onclick = (function(param){ 
 
        return function(){ 
 
        alert("I am button " + param); 
 
         }; 
 
       })(i); 
 
      } 
 

 
     </script> 
 
    </body> 
 
</html>

それとも、コールバックbutton.onclickが閉鎖されES6 feature let

<!DOCTYPE html> 
 
    <html> 
 
     <head> 
 
      <meta charset="utf-8" /> 
 
      <title>Test</title> 
 
     </head> 
 
     <body> 
 
      <p class="button">Button 0</p> 
 
      <p class="button">Button 1</p> 
 
      <p class="button">Button 2</p> 
 
      <script> 
 
       var buttons = document.getElementsByClassName('button'); 
 
       for (let i = 0 ; i < buttons.length ; i++){ 
 
        buttons[i].onclick = function(){ 
 
         alert("I am button " + i); 
 
        } 
 
       } 
 

 
      </script> 
 
     </body> 
 
    </html>

+0

うわー。 (1)私は閉鎖やその目的を理解しておらず、(2)forループが終了した後はもはや存在しないと仮定したので、これは私を得ました。 – Scribblemacher

0

を使用することができ、それがスタックにそのi個の変数への参照を持っていますループの最後の値に等しい

関連する問題