網站製作學習誌

記錄學習製作網站的一切

JavaScript 小陷阱 (7) - IE 在處理 nodeValue 上與其他瀏覽器的差異

這兩天在玩 jQueryjEditable 時,發現一個 IE 一個很怪異的問題,讓我傷腦筋了一陣子。

在處理 IE 上 TD 標籤的 nodeValue 時,它顯示出來的格式竟然與其他瀏覽器不一樣。這實在是令人費解,不論我怎麼修改 jEditable ,這個問題依舊是沒有漂亮的解法。後來 Neo 老大建議我試試 TEXTAREA 及 PRE 標籤時,我才發現 IE 在處理 nodeValue 及 innerHTML 上和其他家瀏覽器有不同的作法。

範例

我用一個簡單的例子來重現一下我遇到的狀況,以下是一個簡單的測試頁面:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=utf-8" />
<title>nodeValue</title>
<script type="text/javascript">
function displayNodeValue(event, element) {
alert(element.childNodes[0].nodeValue);
}
</script>
</head>
<body>
<h2>&lt;DIV&gt;</h2>
<div id="test" onclick="displayNodeValue(event, this);"
style="position: relative; width: 250px;
height: 100px; border: 1px solid #333; background-color: #EEE;">
click me
a b    c
d
</div>
<h2>&lt;PRE&gt;</h2>
<pre id="test" onclick="displayNodeValue(event, this);"
style="position: relative; width: 250px;
height: 100px; border: 1px solid #333; background-color: #EEE;">
click me
a b    c
d
</pre>
<h2>&lt;TEXTAREA&gt;</h2>
<textarea id="myText" rows="8" cols="30"
onclick="displayNodeValue(event, this);">click me
a b    c
d</textarea>
</body>
</html>

大部份的瀏覽器看這個頁面時,會是長成這樣:

瀏覽結果

<DIV> 的 nodeValue

先按一下 DIV 標籤的 clicke me ,這樣會顯示 DIV 標籤裡的文字內容 (也就是 childNodes[0].nodeValue) ;在 Firefox 下會看到:

Firefox Alert

而 Opera 也差不多:

Opera Alert

不過 IE 就怪了:

IE Alert

<PRE> 與 <TEXTAREA> 的 nodeValue

接下來再以 Firefox 和 Opera 測試 <PRE> 及 <TEXTAREA> ,結果和上面顯示的訊息視窗是相同的。那麼 IE 呢?

以下是在 IE 中點選 PRE 標籤和 TEXTAREA 的結果:

IE PRE TEXT Alert

看得出來,這次 IE 顯示的結果是按照原始編排格式。

結論

像 Firefox 和 Opera 這類瀏覽器在 nodeValue 屬性中存放的文字是原始格式,而 IE 存放的則是解譯過的顯示結果。

也就是說 IE 在處理 DIV 標籤這類不保留原始格式的標籤時,在 nodeValue 屬性裡所有文字的「多空格」、「定位」及「換行」等空白字元,都會被當成單一空格來存放;只有在 PRE 或 TEXTAREA 這類會保留文字編排方式的標籤中,才會以原始格式保存。

註:innerHTML 也是有同樣的問題,只是 innerHTML 包含的是整個 <tag>…</tag> 之間的所有 HTML ,而 childNodes[0].nodeValue 只會包含 <tag> 到下一個 <tag> 裡的文字。

瞭解這個原因後,後面的問題就好解了。也就是在 IE 中使用 jEditable 時,要借重一個 TEXTAREA 來額外存放要修改的值;等修改完成後,也要再把這個 TEXTAREA 裡的值更新。

當然這個問題還有其他解法,像 jEditable 範例中使用 Wiki 語法也是一種方式。

Comments