【问题标题】:Javascript: generate dynamically handlerJavascript:动态生成处理程序
【发布时间】:2013-05-28 14:31:20
【问题描述】:

我正在使用 Javascript 编程。

我需要为onclick 事件动态生成事件处理程序。

这里是代码:

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

}

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

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

我该如何解决这个问题?

谢谢。

祝你有美好的一天。

【问题讨论】:

标签: javascript handler


【解决方案1】:

三个选项:

使用生成器函数

通常的方法是为处理程序创建一个构建器函数:

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

buildHandler 构建的函数会关闭来自对 buildHandler 的调用的 index 参数,而不是 i,因此它会看到正确的值。

使用 ES5 的Function#bind

如果您可以依赖 ES5(或者您包含 ES5 shim,因为这是一个可填充的功能),您可以使用 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 这样做,但你可以用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)));
    }
}

工作方式是将click 事件挂接到容器上,然后当点击冒泡(向下?)到它时,它会查看点击的来源并查看它是否(或它的祖先) ) 是我们关心的按钮之一。如果是,我们会采取行动。

【讨论】:

  • 虽然我通常不会为已经被问过一千次的问题给出答案,但我必须给出一个答案,因为它不是另一个将 IIFE 置于循环中的答案。 .所以+1。 :-)
  • 考虑将此添加到常见问题解答stackoverflow.com/tags/javascript/info(也许添加几句话为什么他的代码完全不起作用)。
  • @thg435:感谢您的建议。完成。
猜你喜欢
  • 2012-01-24
  • 2012-10-19
  • 2017-02-12
  • 1970-01-01
  • 2014-09-20
  • 2010-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多