applying an event handler to newly created objects

后端 未结 3 1897
星月不相逢
星月不相逢 2021-01-29 03:14

So my goal is to have 5 boxes and every time one box is clicked a new box appears. The code I wrote for that is this:

window.onload = function(){
    var boxLis         


        
相关标签:
3条回答
  • 2021-01-29 03:25

    You will need to add an onclick event to your newly added box.

    box.onclick = clickHandler;

    0 讨论(0)
  • box.onclick = clickHandler;
    

    There are more elegant ways, but as that's what you're already doing, there's no harm doing what you're doing, now.

    In a different world, you might do something like:

    var master = document.querySelector("#master");
    
    master.addEventListener("click", clickHandler);
    
    function clickHandler (e) {
      var box = e.target;
      var newBox;
      var totalBoxes = master.querySelectorAll(".box").length;
      if (!box.classList.contains("box")) {
        return; // not a box
      }
    
      if (isBlack(box)) {
        changeColour(box, "white");
      } else {
        newBox = makeNewBox(totalBoxes + 1);
        master.appendChild(newBox);
        changeColour(box, "black");
      }
    }
    

    I don't have to worry about further click-handling beyond that, if all of the boxes are descendants of #master. makeNewBox here is simply separating the creation of the object from what you actually want to do with it.

    0 讨论(0)
  • 2021-01-29 03:46

    If you create boxes dynamically after the window.onload handler has already run, then you will have to run some additional code on those dynamically created boxes that assigns the click handler to them after they have been created.

    function clickHandler(eo){
        if(eo.target.style.backgroundColor != "black") {
            eo.target.style.backgroundColor = "black";
            var box = document.createElement("div");
            box.setAttribute("class","box");
    
            // add this line of code to assign the click handler
            box.onclick = clickHandler;
    
            box.setAttribute("id",document.getElementsByClassName("box").length++);
            document.getElementById("Master").appendChild(box);
        }
        else eo.target.style.backgroundColor = "white";
    }
    

    Or, you can use delegated event handling and handle the events from a common parent that is not dynamically created.

    Delegated event handling uses "event bubbling" where events bubble up their parent chain so you can attach a click handler to a common parent and then check e.target in that click handler to see if the click occurred on one of your box elements and then process it one place. In cases of dynamically added content, this can work very well.

    Delegated event handling in your code would look something like this:

    window.onload = function(){
        // put click handler on common box parent and use event bubbling
        document.getElementById("Master").addEventListener("click", clickHandler);
    }
    
    function clickHandler(eo){
        // if this click occurred on one of my boxes
        if (hasClass(eo.target, "box"))
            if(eo.target.style.backgroundColor != "black") {
                eo.target.style.backgroundColor = "black";
                var box = document.createElement("div");
                box.setAttribute("class","box");
                box.setAttribute("id",document.getElementsByClassName("box").length++);
                document.getElementById("Master").appendChild(box);
            }
            else eo.target.style.backgroundColor = "white";
        }
    }
    
    // utility function for checking a class name
    // could also use .classList with a polyfill for older browsers
    function hasClass(elem, cls) {
        var str = " " + elem.className + " ";
        var testCls = " " + cls + " ";
        return(str.indexOf(testCls) !== -1) ;
    }
    
    0 讨论(0)
提交回复
热议问题