简体   繁体   中英

Child div onclick event: onclick on dynamically added children divs doesn't work as intended

I have a parent div to which I add children divs in a loop. For each child I try to add an onclick event - so that the child div would change its color when clicked on:

    var div;
    for (var i=1; i<=size*size; i++)  {
        div = document.createElement("div");
        div.id = i;
        div.style.width = 480/size + "px";
        div.style.height = 480/size + "px";

        div.onclick= function()  {
            div.style.backgroundColor="orange";
        }
        resultNode.appendChild(div);
    }

However only the last div changes its color, no matter what child is clicked on. I suspect its because var div 's last value is the last child, but shouldn't the onclick added to its previous objects remain with those objects once they are added inside resultNode ?

在此处输入图片说明

I also tried adding this loop:

    var children=resultNode.children;
    for (var i=0; i<children.length; i++)  {
        children.item(i).onclick = function()  {
            children.item(i).style.backgroundColor="blue";
            alert(i);
        }
    }

However, it only works for a single child which index varies, depending of the amount of children. If there are only 25 (its the value of size*size in the code) children, the child with index 6 would get colored. If there are 100 children, the 11 th child would get colored, if there are 400 children, 21 th child would get colored. That is always the second div of the second row (there are size*size divs which form a square with size rows and size columns, meaning the div that gets colored is in the size +1 position):

在此处输入图片说明

I don't understand this behavior. Why does this happen and how should I edit the code to achieve the desired result (any child div when clicked on changes its color)?

div does not reference what you are expecting within the click handler, see JavaScript closure inside loops – simple practical example . You can use event.target to reference the element where the event was dispatched

 for (let i = 1; i <= 5; i++) { let div = document.createElement("div"); div.id = i; div.textContent = i; div.onclick = e => e.target.style.backgroundColor = "orange"; resultNode.appendChild(div); } 
 <div id="resultNode"></div> 

Alternatively

 for (let i = 1; i <= 5; i++) { let div = document.createElement("div"); ((div) => { div.id = i; div.textContent = i; div.onclick = e => div.style.backgroundColor = "orange"; resultNode.appendChild(div); })(div) } 
 <div id="resultNode"></div> 

Your code would also work if you just tweak it as below:

var div;
    for (var i=1; i<=size*size; i++)  {
        div = document.createElement("div");
        div.id = i;
        div.style.width = 480/size + "px";
        div.style.height = 480/size + "px";

        div.onclick= function()  {
            this.style.backgroundColor="orange";
        }
        resultNode.appendChild(div);
    }

Inside onclick function just change it to this.style.background = 'orange' instead of div.style.background = 'orange' object. Your code was not working because div object is pointing to your last div.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM