如何将监听器附加到克隆元素?

3

我目前正在学习DOM,遇到了一个问题:当两个或更多克隆元素拥有相同的事件监听器时,我面临困境。

        case 116:
            var myList = document.querySelectorAll(".selected");
            for(var i=0; i<myList.length;i++)
            {
                var node=myList[i].cloneNode(true);
                node.style.top=Math.random()*window.innerHeight-(node.style.height/2)+"px";
                node.style.left=Math.random()*window.innerWidth-(node.style.width/2)+"px";
                node.addEventListener("click",function(e){
                    node.classList.toggle("selected");
                    console.log(e);
                });
                myList[i].parentNode.appendChild(node);
            }
            break;

代码

盒子1是原始盒子,它有自己的EventListener。

盒子2是原始盒子的克隆,能够正确选择和取消选择。

盒子3-4是1-2的克隆,但似乎盒子3和4得到了相同的监听器,因此当我点击盒子4时,它会在盒子3上切换选择状态,而盒子4上则没有任何反应。

我该如何解决这个问题?

非常感谢您的任何帮助。


初始状态是什么?只有一个盒子,盒子2、3和4是使用这段代码添加的吗?要迭代多少次才能获得可见效果? - STT
初始状态是一个盒子。正确。 两次迭代会产生上面的图片。 - ogward
1个回答

1
我认为这是一个作用域问题。你的事件处理程序引用了node,但在循环结束时,node会指向最后创建的方块。您可以使用闭包为每个事件处理程序存储node的值:
(function(node) {

    // 'node' defined here is in it's own scope, so won't be affected by the changes
    // made to the 'node' variable defined in the outer scope of the loop.
    node.addEventListener("click",function(e){
        node.classList.toggle("selected");
        console.log(e);
    });

})(node);

但可能更好的解决方案是在事件处理程序中使用this

node.addEventListener("click",function(e){

    // within an event handler, 'this' references the event's target element
    this.classList.toggle("selected");
    console.log(e);
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接