17

for を使用してループを作成し、onclick イベントでインクリメントしようとしましたが、うまくいきません。

js の一部:

 var gameCase = ['', '', '', '', '', '', '', '', ''], // 9
    itemLists = $('game').getElementsByTagName('li'); // 9 items

    for( var i = 0; i < itemLists.length; i++ ) {
         // i already egal to 9
         itemLists[i].onclick = function() {
              // do something
         }
    }

しかし、この場合、リストの要素をクリックする前に、For ループは既に終了しています。

また、クリックした項目リストを取得して配列に保存したいと思います。gameCase[this] (onclick 関数内) を試してみましたが、それが良い方法かどうかわかりません。

4

4 に答える 4

29

John Resig は、このトピックについて「Secrets of the JavaScript Ninja」( http://ejohn.org/apps/learn/#59 )で詳しく説明しています。

i の値を保持するには、一時的なスコープを作成する必要があります

for ( var i = 0; i < itemLists.length; i++ ) (function(i){ 
  itemLists[i].onclick = function() {
      // do something
  }
})(i);

編集:

var gameCase = ['', '', '', '', '', '', '', '', ''], // 9
$listParent = $('game').find('ul'), // li's parent
itemLists = $('game').getElementsByTagName('li'); // 9 items

var listHandler = (function() {
  var i = 0;

  return function() {
    // $(this) will in here refer to the clicked li
    i++ // increment i

    if ( i === 9 ) {
      $listParent.off('click', 'li', listHandler); //remove eventhandler when i reaches 9
    }
  }
}());

$listParent.on('click', 'li', listHandler); // attach eventhandler to ul element

私は仕事中なので、今はテストできません。

于 2013-04-07T09:12:52.030 に答える
11

リスナーをラップします。

onclick = (function(i) {return function() {
    ...
};})(i);

これにより、変数のスコープの問題が修正されます。

于 2013-04-07T09:09:58.177 に答える
1

あなたの質問を正しく理解していない場合は申し訳ありません。コードから、ゲームタグにあるすべてのリスト要素に onclick ハンドラーを追加しようとしていることがわかりました (おそらくクラス/ID である必要があります)。

for ループは、ユーザーの操作なしでスクリプト タグ/ファイルが読み込まれるときに実行されます。

カウンターの現在値を使用する機能を割り当てたい場合。次のコードを使用します。

itemLists[i].onclick = (function() {
    return function() {
         // TODO ---
        // Your handler code here
}
})();
于 2013-04-07T09:13:03.317 に答える