操作innerHTML 删除子元素的事件处理程序?

IT技术 javascript dom browser dom-events
2021-01-12 23:51:43

我有这个非常简单的演示:

function foo() {
    alert('Works!');
}

var inp = document.createElement('input');
inp.onblur = foo;
document.body.appendChild(inp);

见这里: http : //jsfiddle.net/A7aPA/

如您所见,这是有效的。(单击输入,然后单击其他位置,将弹出警报。)

但是,如果我将此行添加到 JavaScript 代码中:

document.body.innerHTML += '<br>'; 

然后模糊处理程序停止工作(顺便说一句,没有抛出错误)。

见这里: http : //jsfiddle.net/A7aPA/1/

这是为什么?

2个回答

是的,当你这样做时:

document.body.innerHTML += '<br>'; 

你真的在做:

document.body.innerHTML = (document.body.innerHTML + '<br>'); 

因此,您完全破坏并重新创建了所有内容。

@patrick 因此,将字符串添加到元素的 innerHTML 属性将破坏在该元素的后代上设置的所有事件处理程序。天啊!现在我知道:)
2021-03-23 23:51:43
@Šime Vidas:因为并不总是有从一个到另一个的直接映射。我用一个例子更新了我上面的评论,但这是另一个. 这个设置输入.value.idvalue丢失,但id更新的实际属性,因此幸免于难。(检查控制台)。再次更新了我的例子。我使用了无效的 ID
2021-03-25 23:51:43
完成添加 <br> 的更简单方法是创建一个新的 <br> ,就像您创建输入的方式一样,并将其附加到文档正文中,就像您对输入所做的一样。
2021-03-30 23:51:43
@Šime Vidas:是的,但不仅仅是事件处理程序。它会破坏元素本身,因此会破坏处理程序,以及可能已在元素的属性上设置的任何其他数据,这些数据不会显示为属性。例子
2021-04-02 23:51:43
@patrick 嗯,但是为什么浏览器没有在 onblur 属性(在代码中设置)和 onblur 属性之间建立连接?我的意思是,浏览器可以将输入元素字符串化为:<input onblur="foo">,这很简单......
2021-04-08 23:51:43

修改innerHTML会导致重新解析内容并重新创建 DOM 节点,从而丢失您附加的处理程序。在第一个示例中添加元素不会导致该行为,因此不必重新解析,因为您显式修改了 DOM 树。

处理此问题的另一个好方法是使用insertAdjacentHTML()例如:

document.body.insertAdjacentHTML('beforeend', '<br>')
insertAdjacentHTML('','').innerHTML +=
2021-03-14 23:51:43
当您说丢失处理程序时,这是否意味着例如,如果我有innerHTML= '<div onclick=myfunction()>hey</div>并且当我再次这样做时,先前的onclick事件将被删除,或者这会造成内存泄漏吗?
2021-03-19 23:51:43
+1insertAdjacentHTML已经存在了一段时间并且适用于所有主要浏览器。谢谢你指出!
2021-03-29 23:51:43
不,它是关于用 addEventListener 而非 onclick 添加的事件
2021-04-03 23:51:43