Javascript:生成动态处理程序

1 javascript handler

我正在用Javascript编程.

我需要动态生成事件的事件处理程序onclick.

上面的代码如下:

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

}
Run Code Online (Sandbox Code Playgroud)

问题显然是在运行时i变量获得最新值而不是正确值.

但我无法解决问题,因为处理程序不允许该函数的参数.

我怎么解决这个问题?

谢谢.

祝你有美好的一天.

T.J*_*der 6

三种选择:

使用构建器功能

通常的方法是为处理程序提供构建器功能:

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

通过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);
}
Run Code Online (Sandbox Code Playgroud)

像这样使用它会创建不必要的额外功能,所以你也可以像这样使用它:

// 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));
}
Run Code Online (Sandbox Code Playgroud)

使用事件委派

而不是在每个按钮上放置一个处理程序,如果它们都在一个容器中(当然,最终它们就是,即使它只是document.body),你可以把处理程序放在那个容器上然后event.target用来找出哪个按钮是点击.我不会那样做旧式onclick,但你可以用addEventListenerattachEvent:

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)));
    }
}
Run Code Online (Sandbox Code Playgroud)

可行的方法是将click事件挂钩到容器上,然后当点击向上(向下?)到达它时,它会查看点击源自的位置,并查看是否(或其祖先)是其中一个按钮我们关心.如果是,我们就采取行动.