将事件处理程序应用于新创建的对象

时间:2015-12-01 23:21:44

标签: javascript eventhandler

所以我的目标是拥有5个盒子,每次点击一个盒子时会出现一个新盒子。我为此写的代码就是:

window.onload = function(){
    var boxList = document.getElementsByClassName("box");
    for(i = 0; i< boxList.length;i++){
    boxList[i].onclick = clickHandler;
    } 
}

function clickHandler(eo){
    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";
}

所有div的类是&#34; box&#34;我只是为每个新盒子添加一个新的id。我的问题是事件处理程序似乎不适用于新创建的框。怎么能解决?

非常感谢提前!

3 个答案:

答案 0 :(得分:1)

box.onclick = clickHandler;

有更优雅的方式,但正如你已经做过的那样,现在做你正在做的事情没有坏处。

在另一个世界中,您可能会执行以下操作:

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");
  }
}

如果所有的框都是#master的后代,我不必担心进一步的点击处理。 这里的makeNewBox只是将对象的创建与你实际想要用它做的分开。

答案 1 :(得分:0)

如果在window.onload处理程序运行后动态创建框,则必须在动态创建的框上运行一些附加代码,这些框在创建后为其分配单击处理程序。

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";
}

或者,您可以使用委派事件处理并处理来自非动态创建的公共父级的事件。

委托事件处理使用&#34;事件冒泡&#34;事件冒泡其父链,以便您可以将单击处理程序附加到公共父级,然后检查该单击处理程序中的e.target以查看是否在其中一个框元素上发生了单击,然后将其处理到一个位置。在动态添加内容的情况下,这可以很好地工作。

代码中的委托事件处理看起来像这样:

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

答案 2 :(得分:0)

您需要在新添加的框中添加onclick事件。

box.onclick = clickHandler;