关闭在火狐 SDK 中不起作用

closures not working in firefox sdk

本文关键字:不起作用 SDK 火狐      更新时间:2023-09-26

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

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/...但是除了最后一个按钮外,没有一个按钮起作用。最后一个按钮返回正确的索引。

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

当你使用 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);
    }
    

修改 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);
}

小提琴示例