3 つのオプション:
ビルダー関数を使用する
通常の方法は、ハンドラー用のビルダー関数を用意することです。
for (var i = 1; i < CurrValue; i++) {
getId('btnReadRFIDTag_' + i).onclick = buildHandler(i);
}
function buildHandler(index) {
return function() {
ReadRFIDTag(getId('txtCode_' + index));
};
}
によって構築された関数は、 の呼び出しではなく、への呼び出しからbuildHandler
の引数を閉じるため、正しい値が表示されます。index
buildHandler
i
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
ではそれをしませんが、addEventListener
orでできます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つであるかどうかを確認します私たちは気にします。もしそうなら、私たちはそれに基づいて行動します。