操作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 属性之间建立连接?我的意思是,浏览器可以将输入元素字符串化为:<input onblur="foo">
,这很简单......
@Šime Vidas:因为并不总是存在从一个到另一个的直接映射。我用一个例子更新了我上面的评论,但是here's another。这个设置输入的.value
和.id
。 value
丢失了,但 id
更新了实际属性,因此得以幸存。 (检查控制台)。 再次更新了我的示例。我使用了无效的 ID。【参考方案2】:
修改 innerHTML
会导致重新解析内容并重新创建 DOM 节点,从而丢失您附加的处理程序。在第一个示例中添加元素不会导致该行为,因此不必进行重新解析,因为您正在显式修改 DOM 树。
另一个处理这个问题的好方法是使用insertAdjacentHTML()。例如:
document.body.insertAdjacentHTML('beforeend', '<br>')
【讨论】:
+1insertAdjacentHTML
已经存在了一段时间,适用于所有主流浏览器。感谢您指出!
当您说丢失处理程序时,这是否意味着例如如果我有 innerHTML= '<div onclick=myfunction()>hey</div>
并且当我再次这样做时,之前的 onclick
事件将被删除,或者这会造成内存泄漏吗?
不,它是关于使用 addEventListener 添加的事件而不是 onclick
insertAdjacentHTML('','')
比 .innerHTML +=
快以上是关于操作innerHTML 会移除子元素的事件处理程序? [复制]的主要内容,如果未能解决你的问题,请参考以下文章