1

我正在尝试创建一个带有自动分配的 onclick 事件的按钮列表。

document.getElementById('buttonList').innerHTML = '';
for(var $c = 0; $c < $buttons.length; $c++) {
    document.getElementById('buttonList').innerHTML += '<li><button id="button-' + $c + '">' + $buttons[$c].text + '</button></li>';
    document.querySelector('#button-' + $c).onclick = (function($index) {
        return function() {
            console.log($index);
        };
    })($c);
}

在我看来,如果我单击一个按钮,它应该记录 0/1/2/3/... 但是除了最后一个之外,没有一个按钮起作用。最后一个按钮返回正确的索引。

所以我的问题是,有什么问题?

4

2 回答 2

2

当您修改innerHTML属性时,元素会重新呈现,因此您绑定onclick到的元素不再存在于 DOM 中(最后一个除外)。

来自MDN

删除元素的所有子元素,解析内容字符串并将结果节点分配为元素的子元素。

如果您仍想使用innerHTML,解决方案是创建一个容器元素 ( <li>),将其附加到您的列表中,然后修改其innerHTML

document.getElementById('buttonList').innerHTML = '';
for (var $c = 0; $c < $buttons.length; $c++) {
    var liItem = document.createElement("li");
    document.getElementById('buttonList').appendChild(liItem);
    liItem.innerHTML = '<button id="button-' + $c + '">' + $buttons[$c].text + '</button>';
    console.log(document.querySelector('#button-' + $c));
    document.querySelector('#button-' + $c).onclick = (function ($index) {
        return function () {
            console.log($index);
        };
    })($c);
}

小提琴示例

于 2013-11-12T18:43:56.720 回答
2

当您使用innerHTML += ...时,它会破坏旧的onclick处理程序。您可以通过以下两种方式之一解决此问题:

  • 使用appendChild代替innerHTML += ...

    document.getElementById('buttonList').innerHTML = '';
    for(var $c = 0; $c < $buttons.length; $c++) {
        var li = document.createElement('li');
        var button = document.createElement('button');
        button.setAttribute('id', 'button-' + $c);
        button.innerHTML = $buttons[$c].text;
        button.onclick = (function($index) {
            return function() {
                console.log($index);
            };
        })($c);
        li.appendChild(button);
        document.getElementById('buttonList').appendChild(li);
    }
    
  • 首先生成 HTML,然后一次性添加所有事件处理程序:

    document.getElementById('buttonList').innerHTML = '';
    for(var $c = 0; $c < $buttons.length; $c++) {
        document.getElementById('buttonList').innerHTML += '<li><button id="button-' + $c + '">' + $buttons[$c].text + '</button></li>';
    }
    
    for(var $c = 0; $c < $buttons.length; $c++) {
        document.querySelector('#button-' + $c).onclick = (function($index) {
            return function() {
                console.log($index);
            };
        })($c);
    }
    
于 2013-11-12T18:44:26.823 回答