最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Why can event listeners stop working after using element.innerHTML? - Stack Overflow

programmeradmin2浏览0评论

I am a beginner in JavaScript. A JavaScript book says that one of disadvantages of element.innerHTML is:

Event handlers may no longer work as intended.

I can't understand what this mean. Can someone give me an example?

I am a beginner in JavaScript. A JavaScript book says that one of disadvantages of element.innerHTML is:

Event handlers may no longer work as intended.

I can't understand what this mean. Can someone give me an example?

Share Improve this question edited Jul 27, 2021 at 9:32 Brian Tompsett - 汤莱恩 5,88372 gold badges61 silver badges133 bronze badges asked May 25, 2016 at 22:22 Micheal_SongMicheal_Song 1592 silver badges7 bronze badges 1
  • Here is an array/JSON analogy: var obj = [Infinity]; var str = JSON.stringify(obj); str = str.slice(0, -1) + ', 42]'; obj = JSON.parse(str);. This is a very horrible way of adding a new element to the array. The result is the array [null, 42] because JSON cannot represent Infinity. Similarly for DOM, any event handlers bound to an element will be lost if it is converted to HTML because HTML itself cannot store a representation of the bound functions. – Felix Kling Commented May 25, 2016 at 22:44
Add a comment  | 

3 Answers 3

Reset to default 20

Most probably, it refers to the technique some people use to insert HTML at the end:

element.innerHTML += "inserted HTML";

This will get the current HTML, concatenate it with the inserted one, and parse it all.

As a side effect, all the internal state of the existing elements (like event listeners, checkedness, ...) will be lost.

var btn = document.querySelector("button");
btn.addEventListener("click", function() {
  btn.textContent = "I won't work anymore";
  document.body.innerHTML += "<p>Inserted text</p>";
});
<button>Click me to insert HTML</button>

Instead, if you want to insert some HTML at the end of an element, you can use

element.insertAdjacentHTML('beforeend', "inserted HTML");

This will preserve the existing elements.

var btn = document.querySelector("button");
btn.addEventListener("click", function() {
  btn.textContent = "I still work";
  document.body.insertAdjacentHTML("beforeend", "<p>Inserted text</p>");
});
<button>Click me to insert HTML</button>

Another alternative, if you don't mind the inserted content to be wrapped inside an element, is using appendChild:

var btn = document.querySelector("button");
btn.addEventListener("click", function() {
  btn.textContent = "I still work";
  var wrapper = document.createElement('div');
  wrapper.innerHTML = "<p>Inserted text</p>";
  document.body.appendChild(wrapper);
});
<button>Click me to insert HTML</button>

innerHTML is a string representation of html contents of an element. Getting these contents has no side effect but resetting it force the browser to generate new elements.

Each HTML tag in a document is parsed as an unique DOM HTMLElement object by the browsers. Event handlers are bound to these elements. By resetting innerHTML property, browser removes the old elements and makes the DOM parser to create other element objects based on the new html string. When an element is removed it's event handlers are also removed.

Imagine that you have an element that responds to it's click events via a handler, when the element is removed you can't click on it so it makes you feel the handler is also removed. The way event handlers are garbage collected depends on the code that has been written and the way a JavaScript interpreter works.

Because when you dynamically create an element with Javascript with the element.innerHTML function, the newly created element might not respond to Event Listeners methods as intended.

发布评论

评论列表(0)

  1. 暂无评论