Ответ 1
Три варианта:
Использовать функцию Builder
Обычный способ заключается в том, что для обработчиков есть функция-строитель:
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, так как это функция shimmable), вы можете сделать это с помощью 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
, чтобы узнать, какая кнопка была нажата. Я бы не сделал это с помощью старого стиля onclick
, но вы можете с помощью addEventListener
или 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
с контейнером, а затем, когда клик пузырьков вверх (вниз?) к нему, он смотрит, где произошел щелчок, и видит, является ли это (или его предком) ) является одной из кнопок, о которых мы заботимся. Если это так, мы действуем на нем.