IE下JS childNodes属性的疑惑
<div id="test">
<i>test</i>
</div>
var test = document.getElementById("test");
alert(test.childNodes[1].nodeType);
IE 下弹出 3,难道
i
标签后面的空文本也算进去了
IE 不是会忽略空文本节点的吗?
i
标签前面的空文本就没算进去啊!
但是吧
i
标签换成其他的
div
,
p
标签之类就正常的,
但是
i
标签,
em
标签,
b
标签之类的改变字体样式的标签就会出现这个问题,
这是为什么呢,左右不对称啊
浏览器 JavaScript internet-explorer
Answers
W3Help处 有详细的实验过程。
要注意到,IE下, 会影响到渲染的 空文本节点都没有忽略,比如说,行内标签之间的空白节点。在W3C标准中,行内标签之间的空白节点,必须根据white-space属性进行判断,影响渲染。
下面详细解释会影响到渲染的空文本节点。让我们从空白符开始吧。
W3C 9.1 White space 规定了以下字符为空白符:
-
ASCII 空格
-
ASCII 制表符
-
ASCII 换页符
-
零宽度空格
-
折行(line-break)
通常情况下,对于多个连续的空白符(空格,换行符,回车符等),浏览器会将他们合并为一个空白符。CSS 中由white-space
这个属性来控制:——《 inline-block 前世今生 》
- normal:默认处理方式。
- pre:用等宽字体显示预先格式化的文本,不合并文字间的空白距离,当文字超出边界时不换行。可查阅 pre 对象
- nowrap:强制在同一行内显示所有文本,直到文本结束或者遭遇 br 对象。
- pre-wrap:用等宽字体显示预先格式化的文本,不合并文字间的空白距离,当文字碰到边界时发生换行。
- pre-line:保持文本的换行,不保留文字间的空白距离,当文字碰到边界时发生换行。
在接下来的 W3C 16.6.1 The 'white-space' processing model 里讲到空白符是如何参与渲染策略的:
下面是我对标准的翻译
对于每个inline元素(包括匿名的inline元素),下列步骤被执行:
-
若
white-space
设为normal
,nowrap
或pre-line
,U+000A
(linefeed)周边的U+0009
(tab)、U+000D
(carriage return)、U+0020
(space)被舍弃 -
若
white-space
被设为pre
或pre-wrap
,任何不被元素边界破坏的空格序列U+0020
被当做不折行的空格。然而,对于pre-wrap
属性来说,在空格序列末尾有可能出现折行 -
若
white-space
设为normal
或nowrap
,在不一样的UA相关的上下文中,linefeed字符可能被当做空白符中的任意一个,或者没有字符(因此而不被渲染) -
若
white-space
设为normal
,nowrap
或pre-line
,tab字符被转化为空格;同时任何空白符之后的空白符——甚至是inline元素之前的white-space
,只要该white space被应用了white-space:normal | nowrap | pre-line
——会被移除
然后内联元素被排版下来,根据bidi信息被重新排序,然后按照
white-space
属性被包裹(wrap,可以理解为放进块级元素内部)起来。包裹过程中,按照
white-space
属性考虑是否折行。
每行的排版过程中:
-
若
white-space
设为normal
,nowrap
或pre-line
,行首的空格被舍弃 - 所有的tab被渲染为一行的水平位移,直到下一个tab stop处。tab stop出现在每个块级的content-edge开始的每8个空格处
-
若
white-space
设为normal
,nowrap
或pre-line
,行尾的空格被舍弃 -
若
white-space
设为pre-wrap
,行尾的空格和tab可能被UA折叠
浮动定位和绝对定位元素没有新的折行可能。
IE对空白符的解析,正好避免了可能影响到渲染的部分,去掉的空白符是空格在渲染环节被舍弃的部分(非全部,比如行末空白符就被保留了)。
两个过程本不应该混淆:决定空白符是否出现在DOM树中的这一步,发生在构建DOM树的阶段;决定空白符是否被渲染的这一步,发生在构建Rendering树阶段。
这个bug的影响,在于DOM而非CSS,具体而言,遍历childNodes时会有浏览器差异,做额外的判断即可。对于渲染没有区别。
P.S. M$的C++程序员对性能的焦渴导致他们在HTML parse阶段也有意识地控制DOM树大小?