0

ループを介して一連のボタンを作成し、各ボタンの onclick 関数の引数としてループ イテレータを使用しようとしています。

私のコード:

var testFnc = function(i) { alert("Arg: " + i); }

mainDiv.append(create_button(name, "buttonCSS", testFnc(i)));

ただし、ページが読み込まれてボタンが配置されると、関数は自動的に呼び出されます (つまり、すぐにアラートが表示されます)。

これにはいくつかの一般的な設計パターンがあると確信しています。

ありがとう!

4

3 に答える 3

3

1つのアプローチは、ボタンごとに、個別の関数を作成する「自己実行」関数を呼び出すことです。

mainDiv.append(create_button(name, "buttonCSS", (function(i) {

    // For the function below, i comes from
    // this function's scope, not the outside scope.

    return function() {
        testFnc(i);
    };

})(i) ));

これにより、関数外の値を変更し、i既存のボタンに影響を与えないようにすることができます。

(多数のボタン(おそらく数千)を作成している場合は、create_button関数を変更してボタン要素自体にプロパティを追加し、関数にそれをチェックさせる方がよい場合があります。または、コードがInternetExplorerで機能する必要がない場合8以下では、上記のコードの代わりにbind()関数を使用できます。)

于 2012-07-31T20:48:10.137 に答える
2

注:これの非常に詳細な説明については、同じ質問に対する私の以前の回答を参照してください。

  1. 括弧を使用すると、testFncが呼び出さcreate_buttonれ、その戻り値が関数に渡されるため、もちろんすぐにアラートが発生します。代わりに、実際の関数オブジェクトを呼び出さずに渡す必要があります。testFncこれを行うには、無名関数alaをラップしfunction() { testFunc(i); }ます。これにより、すぐにではなく後で実行される関数がどのように返されるかわかりますか?
  2. クリックイベントが実行されると、次の値ではなく、最新のiの値(ループの最後にあった値)が使用されるためi、これ自体はまだ機能しません。バインディングの時間。これを修正するには、コールバックの直接のスコープにのみ配置され、それ以上ではない別の変数の周りに新しいクロージャーを作成します。この変数には、クリックイベントがバインド時の値ではなく、バインド時の値を持つようにが与えられます。バインドされた関数の実行時間。i

    これを行う方法は次のとおりです。

    for (i = 0; i < len; i++) {
       mainDiv.append(
          create_button(name, "buttonCSS", (function(val) {
             return function() {
                testFnc(val);
             };
          }(i)))
       );
    }
    

    少し紛らわしいように見えると思いますが、重要なのは、呼び出された関数(返される関数)を別の関数でラップすると、val外部関数で使用されていない変数を使用して新しいスコープが作成されるということです。これにより、直接の値に対してのみクロージャが作成され、i必要なものからデタッチされます。これについてのより深い説明がここにあります。

このページのもう1つの回答は再利用されiているため、混乱を招く可能性があることに注意してください。それは機能しますiが、参照されている内部関数の内部が不明確です!別の変数名を使用して混乱を避ける方がよいと思います。

于 2012-07-31T20:48:32.443 に答える
0

jQueryを使用していますか?ボタンのクラスを参照できます

<button class='my-custom-class' data-index='0'>This button</button>

とでdocument.ready

$(document).ready(function () {   
  buildButtons();

  $('.my-custom-class').on('click', function () { 
    var index = $(this).attr('data-index');
    alert('Arg: ' + index);
  });
});

jQuerydata-*のプロパティを使用してカスタム属性にアクセスできるため、カスタム属性を使用することをお勧めします。attrこれは、実装できる 1 つの方法です。

于 2012-07-31T20:50:03.120 に答える