ogward
ogward

Reputation: 1193

How do I attach a listener to a cloned element?

I'm currently learning about DOMs and have this problem I'm struggling with when two or more cloned elements get the same event listener.

        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;

the code

box 1 is the original box and it has its own EventListener.

box 2 is the clone of the original and selects and deselects as it should.

box 3-4 are clones of 1-2 but it seems that box 3 and 4 get the same listener because when I click on box 4 it toggles selected on box 3 and nothing happens with box 4.

How do I solve this?

Any help will be most welcome.

Upvotes: 3

Views: 65

Answers (1)

Ben Jackson
Ben Jackson

Reputation: 11922

I think this is a scoping issue. Your event handler is making reference to node, but at the end of the loop, node will point to the last square created. You can store the value of node for each event handler using a closure:

(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);

but probably the better solution is to use this within your event handler:

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

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

Upvotes: 1

Related Questions