操作innerHTML 会移除子元素的事件处理程序? [复制]

Posted

技术标签:

【中文标题】操作innerHTML 会移除子元素的事件处理程序? [复制]【英文标题】:Manipulating innerHTML removes the event handler of a child element? [duplicate] 【发布时间】:2011-07-04 01:00: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/

这是为什么呢?

【问题讨论】:

阅读innerHTML会给你一个字符串。所以document.body.innerHTML = document.body.innerHTML; 会删除你所有的事件... 【参考方案1】:

是的,当你这样做时:

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

你真的在做:

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

所以你完全破坏并重新创建了所有内容。

【讨论】:

@patrick 因此,将字符串添加到元素的 innerHTML 属性将破坏在该元素的后代上设置的所有事件处理程序。天啊!现在我知道:) @Šime Vidas:是的,但不仅仅是事件处理程序。它会破坏元素本身,从而破坏处理程序,以及可能已在元素的属性上设置的任何其他数据,这些数据不会显示为属性。 Example 完成添加 的更简单方法是创建一个新的 ,就像您创建输入一样,并将其附加到文档正文中,就像您对输入所做的那样。 @patrick Hm,但是为什么浏览器没有在 onblur 属性(在代码中设置)和 onblur 属性之间建立连接?我的意思是,浏览器可以将输入元素字符串化为:&lt;input onblur="foo"&gt;,这很简单...... @Šime Vidas:因为并不总是存在从一个到另一个的直接映射。我用一个例子更新了我上面的评论,但是here's another。这个设置输入的.value.idvalue 丢失了,但 id 更新了实际属性,因此得以幸存。 (检查控制台)。 再次更新了我的示例。我使用了无效的 ID【参考方案2】:

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

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

document.body.insertAdjacentHTML('beforeend', '<br>')

【讨论】:

+1 insertAdjacentHTML 已经存在了一段时间,适用于所有主流浏览器。感谢您指出! 当您说丢失处理程序时,这是否意味着例如如果我有 innerHTML= '&lt;div onclick=myfunction()&gt;hey&lt;/div&gt; 并且当我再次这样做时,之前的 onclick 事件将被删除,或者这会造成内存泄漏吗? 不,它是关于使用 addEventListener 添加的事件而不是 onclick insertAdjacentHTML('','').innerHTML +=

以上是关于操作innerHTML 会移除子元素的事件处理程序? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

js 动态给元素添加移除事件

jQuery Dom 系列

jQuery修炼心得-DOM节点的删除

DOM节点的删除(jQuery)

jquery-DOM

unbind() 移除事件内处理方法