IE 在創(chuàng)建 DOM 樹(shù)時(shí)會(huì)忽略某些空白字符
來(lái)源:易賢網(wǎng) 閱讀:1161 次 日期:2015-04-22 11:03:05
溫馨提示:易賢網(wǎng)小編為您整理了“IE 在創(chuàng)建 DOM 樹(shù)時(shí)會(huì)忽略某些空白字符”,方便廣大網(wǎng)友查閱!

標(biāo)準(zhǔn)參考

Node(節(jié)點(diǎn))不僅包括元素節(jié)點(diǎn),也包含文本節(jié)點(diǎn)、注釋節(jié)點(diǎn)、屬性節(jié)點(diǎn)等等,節(jié)點(diǎn)的類型可以使用 nodeType 來(lái)區(qū)分。

在 HTML 源代碼中,位于標(biāo)簽之內(nèi)以及標(biāo)簽之間的文本(包括空白字符)將被創(chuàng)建為文本節(jié)點(diǎn)。

關(guān)于 Node 的更多信息,請(qǐng)參考 DOM-1 Core Interface Node 及 DOM-2 Core Interface Node 中的內(nèi)容。

關(guān)于 Text 的更多信息,請(qǐng)參考 DOM-2 Core Interface Text 中的內(nèi)容。

問(wèn)題描述

IE 在創(chuàng)建 DOM 樹(shù)時(shí),會(huì)忽略某些空白字符,因此會(huì)比其他瀏覽器少創(chuàng)建一些文本節(jié)點(diǎn)。反過(guò)來(lái)說(shuō),同樣的一篇文檔,其他瀏覽器將比 IE 多創(chuàng)建一些文本節(jié)點(diǎn)。

造成的影響

用戶針對(duì) IE 設(shè)計(jì)的腳本如果使用節(jié)點(diǎn)對(duì)象的 nodeList、firstChild、lastChild、previousSibling 或 nextSibling 方法,可能會(huì)因?yàn)榇藛?wèn)題而無(wú)法在其他瀏覽器中達(dá)到相同的目的,如腳本執(zhí)行出錯(cuò),或?qū)﹀e(cuò)誤的目標(biāo)對(duì)象進(jìn)行了操作。

受影響的瀏覽器

IE6 IE7 IE8

問(wèn)題分析

分析以下代碼:

...

<!--測(cè)試元素-->

<div id="a"> <div>div</div> <span id="b">span</span> <span>span</span> </div>

<!--腳本輸出-->

<pre>

<script>

//獲取父元素。

var $a=document.getElementById("a");

//測(cè)試 childNodes。

var nodeList=$a.childNodes;

var string="";

for(var i=0;i<nodeList.length;i++)string+=nodeList[i].nodeType;

document.writeln("nodeList: "+string);

//測(cè)試 firstChild。

document.writeln("firstChild: "+$a.firstChild.nodeType);

//測(cè)試 lastChild。

document.writeln("lastChild: "+$a.lastChild.nodeType);

//獲取子元素。

var $b=document.getElementById("b");

//測(cè)試 previousSibling。

document.writeln("previousSibling: "+$b.previousSibling.nodeType);

//測(cè)試 nextSibling。

document.writeln("nextSibling: "+$b.nextSibling.nodeType);

//顯示 innerHTML。

alert("|"+$a.innerHTML+"|");

</script>

</pre>

...

注意以上代碼,外層 DIV 標(biāo)簽內(nèi)的各標(biāo)簽間有空格符??崭穹粯?biāo)記為紅色。

根據(jù)規(guī)范中的描述,腳本的預(yù)計(jì)輸出情況如下:

第一行輸出應(yīng)該是“nodeList: 3131313”,因?yàn)樵撛貎?nèi)的節(jié)點(diǎn)共有 7 個(gè):3 個(gè)元素節(jié)點(diǎn)穿插在 4 個(gè)文本節(jié)點(diǎn)之間。

第二行輸出應(yīng)該是“firstChild: 3”,第一個(gè)節(jié)點(diǎn)是文本節(jié)點(diǎn)。

第三行輸出應(yīng)該是“l(fā)astChild: 3”,最后一個(gè)節(jié)點(diǎn)也是文本節(jié)點(diǎn)。

第四行輸出應(yīng)該是“previousSibling: 3”。本次的目標(biāo)元素(SPAN[id=b])的前一個(gè)節(jié)點(diǎn)是文本節(jié)點(diǎn)。

第五行輸出應(yīng)該是“nextSibling: 3”,原因同上。

這段代碼在不同的瀏覽器環(huán)境中的表現(xiàn):

IE其他瀏覽器

nodeList:113133131313

firstChild:13

lastChild:33

previousSibling:13

nextSibling:33

最后彈出 DIV[id=a] 元素的 innerHTML 為:

IE

|<DIV>div</DIV><SPAN id=b>span</SPAN> <SPAN>span</SPAN> |

其他瀏覽器:

| <div>div</div> <span id="b">span</span> <span>span</span> |

對(duì)原代碼中的“測(cè)試元素部分”進(jìn)行改動(dòng)后(將其中第二個(gè) SPAN 更換為 DIV 元素):

...

<!--測(cè)試元素-->

<div id="a"> <div>div</div> <span id="b">span</span> <div>div</div> </div>

...

再次測(cè)試,各瀏覽器表現(xiàn)如下:

IE6 IE7 IE8Firefox Chrome Safari Opera

nodeList:11313131313

firstChild:13

lastChild:13

previousSibling:13

nextSibling:33

最后彈出 DIV[id=a] 元素的 innerHTML 為:

IE

|<DIV>div</DIV><SPAN id=b>span</SPAN>

<DIV>div</DIV>|

其他瀏覽器:

| <div>div</div> <span id="b">span</span> <div>div</div> |

可見(jiàn):IE 在生成 DOM 樹(shù)時(shí),忽略了一些空白字符,從而比其他瀏覽器少創(chuàng)建了一些文本節(jié)點(diǎn)。這導(dǎo)致在使用 nodeList、firstChild、lastChild、previousSibling 或 nextSibling 方法時(shí),在 IE 和其他瀏覽器中得到的結(jié)果不一致。

解決方案

1. 沒(méi)有必要時(shí)盡量去掉各標(biāo)簽之間的空白字符。

因?yàn)轫?yè)面腳本多是對(duì)“元素節(jié)點(diǎn)”進(jìn)行操作,因此只要保證各元素之間沒(méi)有文本節(jié)點(diǎn)(即源代碼中的標(biāo)簽之間沒(méi)有空白字符——包括空格符、換行符、制表符),就能使上述各屬性在各瀏覽器中的行為一致。如:

<div id="a"><div>div</div><span id="b">span</span><span>span</span></div>

另外,使用腳本創(chuàng)建并順次添加的元素,他們本身就是緊密相聯(lián)的,各元素之間并沒(méi)有文本節(jié)點(diǎn),因此這種情況也不必?fù)?dān)心上述兼容性問(wèn)題,如:

...

var $a=document.createElement("div");

...

var $b=document.createElement("div");

...

document.body.appendChild($a);

document.body.appendChild($b);

...

$a.nextSibling.className="foo";

...

上述代碼中,'$a.nextSibling' 在所有瀏覽器中都將是 $b。

2. 在獲取節(jié)點(diǎn)時(shí)做類型判斷。

無(wú)法保證各元素之間沒(méi)有文本節(jié)點(diǎn)時(shí),則需要在針對(duì)節(jié)點(diǎn)的操作上添加類型判斷,如:

function getPreviousElementSibling ($target) {

var $previousNode = $target.previousSibling;

while ($previousNode && $previousNode.nodeType!=1) {

$previousNode = $previousNode.previousSibling;

}

return $previousNode;

}

另外,在非IE中,還可以使用 Element Traversal Specification 草案中提到的 previousElementSibling 和 nextElementSibling 獲取元素節(jié)點(diǎn),例如:以 Element.nextElementSibling 取得與元素 Element 的相鄰的下一個(gè)元素節(jié)點(diǎn)。

更多信息請(qǐng)查看IT技術(shù)專欄

更多信息請(qǐng)查看腳本欄目
由于各方面情況的不斷調(diào)整與變化,易賢網(wǎng)提供的所有考試信息和咨詢回復(fù)僅供參考,敬請(qǐng)考生以權(quán)威部門公布的正式信息和咨詢?yōu)闇?zhǔn)!

2025國(guó)考·省考課程試聽(tīng)報(bào)名

  • 報(bào)班類型
  • 姓名
  • 手機(jī)號(hào)
  • 驗(yàn)證碼
關(guān)于我們 | 聯(lián)系我們 | 人才招聘 | 網(wǎng)站聲明 | 網(wǎng)站幫助 | 非正式的簡(jiǎn)要咨詢 | 簡(jiǎn)要咨詢須知 | 加入群交流 | 手機(jī)站點(diǎn) | 投訴建議
工業(yè)和信息化部備案號(hào):滇ICP備2023014141號(hào)-1 云南省教育廳備案號(hào):云教ICP備0901021 滇公網(wǎng)安備53010202001879號(hào) 人力資源服務(wù)許可證:(云)人服證字(2023)第0102001523號(hào)
云南網(wǎng)警備案專用圖標(biāo)
聯(lián)系電話:0871-65099533/13759567129 獲取招聘考試信息及咨詢關(guān)注公眾號(hào):hfpxwx
咨詢QQ:526150442(9:00—18:00)版權(quán)所有:易賢網(wǎng)
云南網(wǎng)警報(bào)警專用圖標(biāo)