在循环中添加addEventListener()仅适用于最后一个按钮 [英] Adding addEventListener() in loop only works for last button

查看:222
本文介绍了在循环中添加addEventListener()仅适用于最后一个按钮的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我从dynamodb获取一个json数组,并在遍历按钮时将addEventListener()添加到按钮。但是只有最后一个按钮对此作出响应。

I get an json-array from dynamodb and is adding an addEventListener() to a button while traversing it. But only the last button responds to this.

这已经是在SO上问过,它是google上的首个热门产品,因此我将循环改为使用闭包。但是除了最后一个按钮,我仍然无法将addEventListener()附加到其他按钮上。

This has been asked before on SO and was the first hit on google so I changed the loop to use closures. But I still can't attach an addEventListener() to other than the last button.

我最初尝试这样做:

for (var i = 0; i < array_length; ++i) {
    (function(j) {
        var obj = data.Items[j];

        adiv.innerHTML = adiv.innerHTML + "<div class='row'><div class='center-div six columns'>" + obj.Event + ", " + obj.Location + "</div></div>";
        adiv.innerHTML = adiv.innerHTML + "<div class='row'><div class='center-div six columns'>" + obj.Date + ", " + obj.Time + "</div></div>";
        adiv.innerHTML = adiv.innerHTML + "<div class='row'><div class='center-div six columns'><button id='yay_button_" + i + "' class='button-primary'>Deltag</button></div></div>";

        var elem = document.getElementById('yay_button_' + j);
        elem.addEventListener('click', function() {
            alert('id: ' + j);
        });
    })(i);
}

然后是这个较短的版本:

And then this shorter version:

(function(j) {
    document.getElementById('yay_button_' + j).addEventListener('click', function() {
        alert('id: ' + j);
    });
}(i));

另一个我试图使用新的按钮创建按钮:

Another variant I tried was to create a button using new:

function Button(id, number) {
    document.getElementById(id + number).addEventListener('click', function() {
        alert('click: ' + id + number);
    });
}

new Button('yay_button_', i);

我在capitan上尝试了Safari和chrome都没有出现控制台错误。当我检查按钮时,按钮具有正确的ID,即yay_button_0和_1。

I tried both safari and chrome on el capitan without errors in the console. The buttons has the correct id when I inspect it, yay_button_0 and _1.

推荐答案

主要问题是您重新定义了HTML每次迭代时, adiv 完全。这意味着您已经绑定到 adiv 的子元素的任何事件处理程序都会在您执行 adviv.innerHTML = ...时丢失。 code>。尽管您分配了相同的HTML加上一些新的HTML,但并未分配先前定义的事件处理程序。因此,它们会丢失。

The main problem is that you redefine the HTML of adiv completely every time you iterate. This means that any event handler you had already bound to a child element of adiv is lost the moment you do adviv.innerHTML = .... Although you assign the same HTML plus some new one, you don't assign the event handlers that were previously defined. So they are lost.

只有您在上一次迭代中分配的事件处理程序不会以这种方式销毁。

Only the event handler you assign at the last iteration is not destroyed in this way.

一种快速的解决方案是先循环创建所有HTML,然后再做一个单独的循环来分配事件处理程序:

A quick solution would be to first loop to create all the HTML, and then do a separate loop to assign the event handlers:

// First add all the new content:
var html = adiv.innerHTML;
for (var i = 0; i < array_length; ++i) {
    var obj = data.Items[i];

    html += "<div class='row'><div class='center-div six columns'>" + obj.Event + ", " + obj.Location + "</div></div>";
    html += "<div class='row'><div class='center-div six columns'>" + obj.Date + ", " + obj.Time + "</div></div>";
    html += "<div class='row'><div class='center-div six columns'><button id='yay_button_" + i + "' class='button-primary'>Deltag</button></div></div>";
}
adiv.innerHTML = html;

// Now bind the event handlers
// By using "let" instead of "var" the right value is retained
// in the handlers
for (let i = 0; i < array_length; ++i) {
    var elem = document.getElementById('yay_button_' + i);
    elem.addEventListener('click', function() {
        alert('id: ' + i);
    });
}

如果您的浏览器不支持ES2015(对于 let ),则您可以使用 bind

If your browser does not support ES2015 (for let), then you can use bind:

for (var i = 0; i < array_length; ++i) {
    var elem = document.getElementById('yay_button_' + i);
    elem.addEventListener('click', function(i) {
        alert('id: ' + i);
    }.bind(null, i));
}

这篇关于在循环中添加addEventListener()仅适用于最后一个按钮的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆