Действительно ли возможно добавить к innerHTML, не уничтожая слушателей события потомков?

В следующем примере кода я присоединяю onclick обработчик событий к промежутку, содержащему текст "нечто". Обработчик является анонимной функцией, которая открывается alert().

Однако, если я присваиваю родительскому узлу innerHTML, это onclick обработчик событий уничтожается - нажатию на "нечто" не удается открыться окно предупреждений.

Действительно ли это является закрепляемым?

<html>
 <head>
 <script type="text/javascript">

  function start () {
    myspan = document.getElementById("myspan");
    myspan.onclick = function() { alert ("hi"); };

    mydiv = document.getElementById("mydiv");
    mydiv.innerHTML += "bar";
  }

 </script>
 </head>

 <body onload="start()">
   <div id="mydiv" style="border: solid red 2px">
     <span id="myspan">foo</span>
   </div>
 </body>

</html>
98
задан Brian Tompsett - 汤莱恩 21 August 2019 в 18:52
поделиться

3 ответа

К сожалению, присвоение на innerHTML причины разрушение всех дочерних элементов, даже при попытке добавить. Если Вы захотите сохранить дочерние узлы (и их обработчики событий), то необходимо будет использовать функции DOM :

function start() {
    var myspan = document.getElementById("myspan");
    myspan.onclick = function() { alert ("hi"); };

    var mydiv = document.getElementById("mydiv");
    mydiv.appendChild(document.createTextNode("bar"));
}

Редактирование: решение Bob's, из комментариев. Отправьте свой ответ, Bob! Получите кредит для него.:-)

function start() {
    var myspan = document.getElementById("myspan");
    myspan.onclick = function() { alert ("hi"); };

    var mydiv = document.getElementById("mydiv");
    var newcontent = document.createElement('div');
    newcontent.innerHTML = "bar";

    while (newcontent.firstChild) {
        mydiv.appendChild(newcontent.firstChild);
    }
}
115
ответ дан Ben Blank 24 November 2019 в 05:15
поделиться

Как небольшое (но связанный) в стороне, если Вы пользуетесь библиотекой JavaScript, такой как jQuery (v1.3), чтобы сделать Ваше dom управление, можно использовать прямые трансляции, посредством чего Вы настраиваете обработчик как:

 $("#myspan").live("click", function(){
  alert('hi');
});

и это будет применено к тому селектору в любом случае во время любого вида управления jQuery. Поскольку прямые трансляции видят: docs.jquery.com/events/live для управления jQuery видит: docs.jquery.com/manipulation

2
ответ дан Cargowire 24 November 2019 в 05:15
поделиться

Потеря обработчиков событий, IMO, ошибка в способе, которым JavaScript обрабатывает DOM. Для предотвращения этого поведения можно добавить следующее:

function start () {
  myspan = document.getElementById("myspan");
  myspan.onclick = function() { alert ("hi"); };

  mydiv = document.getElementById("mydiv");
  clickHandler = mydiv.onclick;  // add
  mydiv.innerHTML += "bar";
  mydiv.onclick = clickHandler;  // add
}
0
ответ дан Yes - that Jake. 24 November 2019 в 05:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: