修改div的innerHTML清空全部内容:为何<div></div>与<div />不等价?
<div></div>和<div />并不等价? 这个问题其实戳中了HTML解析器的一个关键规则——不是所有标签都能随便用自闭合写法的,咱们结合你给的代码来拆解一下:
<script> setTimeout(function() { document.getElementById("message2").innerHTML = "blah"; }, 1000); </script> <html> <head> <title>Test</title> </head> <body> <div id="message2" /> <div id="message1" >Hello</div> </body> </html>
现象拆解
运行这段代码时,一开始页面显示“Hello”,但1秒后“Hello”突然消失,取而代之的是“blah”。这看起来有点奇怪,但本质是解析器对<div />的处理和你预想的不一样。
核心原因:HTML对自闭合标签的限制
在HTML里,只有空元素(Void Elements) 才支持自闭合写法,比如<img>、<input>、<br>这类本身就不需要内容的标签。而<div>属于非空元素,HTML解析器根本不承认<div />是一个闭合的标签——它会把这个写法当成一个未闭合的<div>起始标签。
那回到你的代码结构:
<div id="message2" /> <div id="message1" >Hello</div>
解析器会把<div id="message1">Hello</div>当成message2这个div的子元素。当1秒后JS执行message2.innerHTML = "blah"时,会把message2内部的所有内容(包括message1整个div)全部替换成“blah”,所以原来的“Hello”就被覆盖消失了。
如果把<div id="message2" />改成标准的<div id="message2"></div>,两个div就变成了同级元素,修改message2的内容只会影响它自己,message1的“Hello”就会一直保留在页面上。
补充说明
可能有人会疑惑:XHTML里不是允许所有标签自闭合吗?但现在主流浏览器都是按照HTML5的解析规则处理页面,哪怕你写了XHTML的声明,只要不是在严格的XML模式下,解析器依然会按HTML规则来处理非空元素的自闭合写法。所以写HTML时,非空元素一定要用完整的起始+闭合标签,别图省事用自闭合。
内容的提问来源于stack exchange,提问作者Attilio

