JS:innerHTML 和 DOM 不合作

Posted

技术标签:

【中文标题】JS:innerHTML 和 DOM 不合作【英文标题】:JS: innerHTML and DOM aren't cooperating 【发布时间】:2011-04-30 14:02:15 【问题描述】:

我注意到一个有趣的行为,想知道是否有人可以解释原因。

它是这样分解的:

我使用 javascript 的 `appendChild' 添加了 divbutton。 我向按钮添加了一个onclick 处理程序,工作正常 我添加-分配divinnerhtml 以添加更多内容 按钮 onclick 完全停止工作

这是一个示例脚本:

var D = document.createElement("DIV"), B = document.createElement("BUTTON");
B.innerHTML = "Is it true?";
document.body.appendChild(D);
D.appendChild(B);

B.onclick = function()  alert("Elvis Lives!"); 

此时,它工作正常。然后,添加这一行:...

D.innerHTML += "What about Tupac?"; 

...按钮坏了。所以,我现在只对所有元素使用appendChild

但是——

为什么会发生这种情况(“看起来应该可以了 :)”) 是否有修复(除了附加我所有的额外元素)?

【问题讨论】:

【参考方案1】:

(这是很多有根据的猜测)我认为当您修改DinnerHTML 时,D 中的 dom 被销毁并从新值创建。所以当新的内容被构建时,你会得到一个全新的button,它与B 不是同一个节点。由于您通过 js 而不是通过原始元素上的属性设置 onclick 处理程序,因此新的 button 没有该函数引用。但是B 仍然可以通过调用

来演示
B.click();

在您附加到innerHTML 之后。

为了防止 D 中的 dom 颠簸,您可以这样做而不是使用 innerHTML

D.appendChild(document.createTextNode("What about Tupac?"));

【讨论】:

对我来说听起来不错,但我可能会等待其他一些意见。对,我到处都在使用appendChild,但innerHTML 只是简单了几行......【参考方案2】:

innerHTML 是创建 DOM 元素的快捷方式。当您使用 innerHTML 将某些内容附加到外部 div 时,会发生以下情况:

D.innerHTML += "What about Tupac?";

与,

D.innerHTML = D.innerHTML + "What about Tupac?";

与,

D.innerHTML = "<button>Is it true?</button>" + "What about Tupac?";

最后变成了这个,

D.innerHTML = "<button>Is it true?</button>What about Tupac?";

现在在最后一步,我们用一个包含 HTML 的新字符串完全替换了 div 的现有内容。就 DOM 而言,它不关心用户是手动键入 HTML 还是来自在 DOM 节点上调用 innerHTML。它所关心的是,它有一个必须转换为 DOM 的 HTML 字符串。此时会创建一个新的按钮元素,这就是 onclick 停止工作的原因 - 它不再是同一个元素了。

【讨论】:

【参考方案3】:

不是答案,只是一个测试页 - 看起来很奇怪 - 我可以确认你的发现

<script>
window.onload=function() 
  var D = document.createElement("DIV"), B = document.createElement("BUTTON");
  D.id = "div1"
  B.innerHTML = "Is it true?";
  B.onclick = function()  alert("Elvis Lives!"); 
  D.appendChild(B);
  document.body.appendChild(D);

</script>
<a href="" onclick="document.getElementById('div1').innerHTML += 'What about Tupac?'; return false">Click</a><br>
<a href="" onclick="alert(document.getElementsByTagName('button')[0].onclick); return false">Test</a>

更新:经验教训 - 保持一致。

这按预期工作

<script>
window.onload=function() 
  var D = document.createElement("DIV");
  D.id = "div1"
  D.innerHTML = '<button onclick="alert(\'Elvis Lives!\')">Elvis</button>'
  document.body.appendChild(D);

</script>
<a href="" onclick="document.getElementById('div1').innerHTML += 'What about Tupac?'; return false">Click</a><br>

【讨论】:

我什至无法低下自己来瞥见一个看起来很奇怪的页面!这个混蛋是什么? :) 开玩笑。感谢您的确认...

以上是关于JS:innerHTML 和 DOM 不合作的主要内容,如果未能解决你的问题,请参考以下文章

JS DOM知识点

jacascript DOM节点——节点内容

廖雪峰js教程笔记12 用DOM更新 innerHMTL 和修改css样式

HTML DOM 属性

如何在 JS 和 DOM 中创建元素、设置属性、使用 innerHTML 和 appendChild

JS的dom获取innerHtml和innerText的区别