1

私はJavascriptでプログラミングしています。

イベントのイベント ハンドラーを動的に生成する必要がありますonclick

ここのコードの上:

for (var i = 1; i < CurrValue; i++) {
    getId('btnReadRFIDTag_' + i).onclick = function () 
    {
        ReadRFIDTag(getId('txtCode_' + i));
    };

}

問題は、明らかに、実行時にi変数が正しい値ではなく最新の値を取得することです。

しかし、ハンドラーが関数のパラメーターを許可していないため、問題を修正できません。

どうすればこの問題を解決できますか?

ありがとうございました。

良い一日を過ごしてください。

4

1 に答える 1

6

3 つのオプション:

ビルダー関数を使用する

通常の方法は、ハンドラー用のビルダー関数を用意することです。

for (var i = 1; i < CurrValue; i++) {
    getId('btnReadRFIDTag_' + i).onclick = buildHandler(i);
}
function buildHandler(index) {
    return function() {
        ReadRFIDTag(getId('txtCode_' + index));
    };
}

によって構築された関数は、 の呼び出しではなく、への呼び出しからbuildHandlerの引数を閉じるため、正しい値が表示されます。indexbuildHandleri

ES5 を使用するFunction#bind

ES5 に依存できる場合 (または、シム可能な機能であるため、ES5 シムを含める場合)、次のように実行できますFunction#bind

// Using Function#bind (option 1)
for (var i = 1; i < CurrValue; i++) {
    var elm = getId('btnReadRFIDTag_' + i);
    elm.onclick = function(index) {
        ReadRFIDTag(getId('txtCode_' + index));
    }.bind(elm, i);
}

そのように使用すると、不要な余分な関数が作成されるため、次のように使用することもできます。

// Using Function#bind (option 2)
for (var i = 1; i < CurrValue; i++) {
    var elm = getId('btnReadRFIDTag_' + i);
    elm.onclick = myHandler.bind(elm, i);
}

function myHandler(index) {
    ReadRFIDTag(getId('txtCode_' + index));
}

イベントの委任を使用する

各ボタンにハンドラーを配置する代わりに、それらがすべてコンテナー内にある場合 (そしてもちろん、最終的にはコンテナー内にある場合でもdocument.body)、そのコンテナーにハンドラーを配置し、使用event.targetしてどのボタンがあったかを調べることができます。クリックしました。私は old-styleonclickではそれをしませんが、addEventListenerorでできますattachEvent:

var container = /* ...get the container... */;
if (container.addEventListener) {
    container.addEventListener('click', clickHandler, false);
}
else if (container.attachEvent) {
    container.attachEvent('onclick', function(e) {
       return clickHandler.call(this, e || window.event);
    });
}
else {
    // I wouldn't bother supporting something that doesn't have either
}

function clickHandler(e) {
    var btn = e.target;
    while (btn && btn !== this && btn.id.substring(0, 15) !== "btnReadRFIDTag_") {
        btn = btn.parentNode;
    }
    if (btn && btn !== this) {
        ReadRFIDTag(getId('txtCode_' + btn.id.substring(15)));
    }
}

動作する方法は、コンテナにイベントをフックするclickことです。次に、クリックがコンテナにバブルアップ(ダウン?)すると、クリックが発生した場所を調べ、それ(またはその先祖)がボタンの1つであるかどうかを確認します私たちは気にします。もしそうなら、私たちはそれに基づいて行動します。

于 2013-05-28T14:34:10.073 に答える