применение обработчика событий к вновь созданным объектам

Итак, моя цель - иметь 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-ов - "box", и я просто добавляю новый идентификатор к каждому новому ящику. Моя проблема в том, что обработчик событий, похоже, не работает для вновь созданных ящиков. Как это можно было решить?

Спасибо заранее!


person user3553471    schedule 01.12.2015    source источник
comment
добавить box.onclick = clickHandler; после document.getElementById (Master) .appendChild (box) ;. это потому, что вы не назначили обработчик onclick новым объектам.   -  person NPToita    schedule 02.12.2015
comment
Я думаю, что ваши обработчики событий работают, я использовал ваш код и поместил предупреждения в clickHandler, и они всплывали .. Я думаю, ваша проблема в другом, может быть, поля перекрываются, пожалуйста, поместите также свой HTML-код ..   -  person hagrawal    schedule 02.12.2015


Ответы (3)


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 здесь просто отделяет создание объекта от того, что вы действительно хотите с ним делать.

person Norguard    schedule 01.12.2015

Вам нужно будет добавить событие onclick в новое добавленное поле.

box.onclick = clickHandler;

person orso.zed    schedule 01.12.2015

Если вы создаете блоки динамически после того, как обработчик 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";
}

Или вы можете использовать делегированную обработку событий и обрабатывать события от общего родителя, который не создается динамически.

Делегированная обработка событий использует «восходящую цепочку событий», когда события всплывают в своей родительской цепочке, поэтому вы можете прикрепить обработчик кликов к общему родительскому элементу, а затем проверить 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) ;
}
person jfriend00    schedule 01.12.2015