1

重複の可能性:
ループ内の Javascript クロージャー - 簡単な実用例

次のように、JS を使用して Web サイトの複数の href にイベント ハンドラーを追加します。

function addButtonListener(){
  var buttons = document.getElementsByClassName("selLink");
  for (var i = 0; i < buttons.length; i++)
  {
      button.addEventListener('click',function() { addTosel(i); },true);
    }
  }
}

残念ながら、addTosel には、ループからの i ではなく、最後の i が渡されます。この瞬間に処理されているオブジェクトに応じて i を渡す方法は?

4

3 に答える 3

2

クロージャーを作成する必要があります。

function addButtonListener(){
    var buttons = document.getElementsByClassName("selLink");

    for (var i = 0; i < buttons.length; i++) {

        button.addEventListener('click', function(index) { 
            return function () {
                addTosel(index);
            };
        }(i), true);
    }
}

このようにして、ハンドラのスコープは の適切なコンテキストにバインドされますi

この件に関する詳細については、この記事を参照してください。

于 2012-09-08T12:16:46.370 に答える
0

i宣言時に変数を関数にバインドする必要があります。そのようです

for (var i = 0; i < buttons.length; i++) {
  button.addEventListener('click',(function() { addTosel(this); }).bind(i) ,true);
}

注:私はメモリからコードを書いたばかりなので、完璧ではないかもしれませんが、適切な方法、つまりクロスブラウザシムなどを参照するために必要なソリューションです:

https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/bind

于 2012-09-08T12:20:09.520 に答える
0

.bindアプローチする場合は、このようにします。

for (var i = 0; i < buttons.length; i++) {
   button.addEventListener('click', addTosel.bind(null, i), true);
}

これは、関数がそれを必要としないように見えるためnull、値としてバインドされた新しい関数を作成し、現在のバインドを最初の引数として作成します。thisi

または独自のバインダー機能を作成する

var _slice = Array.prototype.slice;
function _binder(func, ctx /*, arg1, argn */) {
    var bound_args = _slice.call(arguments, 2);
    return function() {
        return func.apply(ctx, bound_args.concat(_slice.call(arguments)));
    }
}

そして、これを行います。

for (var i = 0; i < buttons.length; i++) {
   button.addEventListener('click', _binder(addTosel, null, i), true);
}
于 2012-09-08T13:33:43.160 に答える