Javascript事件处理程序总是被添加到数组中的最后一个对象

标签 javascript dom-events addeventlistener vbulletin

我正在尝试在“切换折叠”按钮(实际上是一个图像)上执行两项任务:

  1. 如果页面的一部分以折叠方式加载(从 cookie),则将“collapsed”类添加到祖先标记中。
  2. 添加一个事件处理程序,以在单击按钮时切换“折叠”类的存在。

为此,我有以下代码:

function toggleCollapsedPlugin(sender, collapseState) {
    // do something
    // expects 1 OR 2 arguments
}

function initCollapsedPlugin() {
    var forumcats = document.getElementById('forums').getElementsByClassName('forumbit_nopost L1');
    var button;
    var buttonParent;
    for (var i = 0; i < forumcats.length; i++) {
        button = forumcats[i].getElementsByTagName('a')[1].getElementsByTagName('img')[0]; // will always exist
        buttonParent = button.parentNode.id; // will never be empty
        if (button.src.indexOf('_collapsed') >= 0) {
            toggleCollapsedPlugin(button.parentNode.id, true);
        }
        button.addEventListener('click', function () { toggleCollapsedPlugin(buttonParent); }, false);
    }
}

当我走过initCollapsedPlugin()时对于 Chrome DevTools 中的第一项,一切似乎都很好。当我稍后单击其中一张图像来调用toggleCollapsedPlugin(sender)时, sender始终等于buttonParent forumcats最后项目的。有人可以解释一下为什么以及如何解决这个问题吗?

(如果它可以帮助任何人提供答案,那就是 vBulletin4 软件。)

最佳答案

这是 JavaScript 闭包的一个典型“陷阱”。基本上,您的 buttonParent 变量在每次迭代中都会被覆盖,并且您传递给 addEventListener 的匿名函数引用但不复制此变量。

您可能需要类似的东西:

button.addEventListener('click', (function (parent) {
    return function() {
        toggleCollapsedPlugin(parent);
    };
})(buttonParent), false);

更详细的解释,请参见How do JavaScript closures work? .

但是,在您的情况下,您可以简单地完全摆脱封闭变量,并在调用匿名函数时找到按钮的父级。这是有效的,因为回调函数内部的 this 引用了事件注册的元素,即该迭代中由 button 引用的元素。

button.addEventListener('click', function() {
    return toggleCollapsedPlugin(this.parentNode.id);
}, false);

关于Javascript事件处理程序总是被添加到数组中的最后一个对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11453105/

相关文章:

javascript - 逗号未正确放置在 keyup 的输入中

javascript - 如何防止长按结束时发出点击声?

javascript - 在决定如何将回调传递给 addEventListener 时,我应该考虑什么?

javascript - d3 中的短路事件?

javascript - 将数据传递给点击监听器

javascript - 绑定(bind)到事件监听器时 beforeunload 不起作用

javascript - 防止 Google 图表 X 轴中日期时间列的舍入

javascript - 如何使用 JavaScript 自动计算页面加载付款?

javascript - jquery中的简单数学

javascript - 为日期字段 extjs 添加自动斜杠