通过 HTML 字符串添加的元素会禁用先前元素的 onclicks/事件侦听器
小提琴:https://jsfiddle.net/eptcrwfd/37/
解决方案是将 onclick 声明放在 setTimeout 中,时间最短
setTimeout(() => {
document.getElementById("element-id").onclick = () => {
console.log(1)
}
})
但这似乎不是最好的方法,我仍然想知道是什么导致了这种行为
表达
document.body.innerHTML += ...
并不像你想象的那么优雅或高效。它实际上是的简写符号
+=
运算符后面并且这不仅非常慢,而且还会删除所有先前分配的事件侦听器。
向现有元素添加新的 HTML 代码块的更安全、更有效的方法是
document.body.insertAdjacentHTML("beforeend","... new HTML code")
。这将使之前构建的 DOM 保持完整,包括所有事件侦听器。
function addButtons(){
const a = document.createElement("button")
a.innerHTML = "button1"
a.className = "button"
a.id = "button-1"
document.body.appendChild(a)
//works only when done this way
setTimeout(()=>{
document.getElementById("button-1").onclick = ()=>
{console.log(1)}
})
document.body.insertAdjacentHTML("beforeend",
"<button id='button2' class='button'>button2</button>")
document.getElementById("button2").onclick = ()=>{console.log(2)}
}
function addButtons1(){
const a = document.createElement("button")
a.innerHTML = "button3"
a.className = "button"
//works when button4 is absent
a.addEventListener("click", ()=>{console.log(3)})
document.body.appendChild(a)
document.body.insertAdjacentHTML("beforeend",
"<button id='button4' class='button'>button4</button>")
//works
document.getElementById("button4").onclick = ()=>{console.log(4)}
}
function addButtons2(){
const a = document.createElement("button")
a.innerHTML = "button5"
a.className = "button"
//works
a.onclick = ()=>{console.log(5)}
document.body.appendChild(a)
const b = document.createElement("button")
b.innerHTML = "button6"
b.className = "button"
//works
b.onclick = ()=>{console.log(6)}
document.body.appendChild(b)
}
addButtons()
addButtons1()
addButtons2()