JS操作文字節點(非常詳細)

2020-07-16 10:05:12
文字節點表示元素和屬性的文字內容,包含純文字內容、跳脫字元,但不包含 HTML 程式碼。文字節點不包含子節點。主要特徵值:nodeType 等於 3、nodeName 等於 "#text"、nodeValue 等於包含的文字。

建立文字節點

使用 document 物件的 createTextNode() 方法可建立文字節點。用法如下:

document.createTextNode(data)

引數 data 表示字串。

範例

下面範例建立一個新 div 元素,並為它設定 class 值為 red,然後新增到文件中。
var element = document.createElement("div");
element.className = "red";
document.body.appendChild(element);

由於 DOM 操作等原因,可能會出現文字節點不包含文字,或者接連出現兩個文字節點的情況。為了避免這種情況的發生,一般會在父元素上呼叫 normalize() 方法,刪除空文字節點,合併相鄰文字節點。

存取文字節點

使用 nodeValue 或 data 屬性可以存取文字節點包含的文字。使用 length 屬性可以獲取包含文字的長度,利用該屬性可以遍歷文字節點中每個字元。

範例

設計一個讀取元素包含文字的通用方法。
//獲取指定元素包含的文字
//引數:e 表示指定元素
//返回包含的所有文字,包括子元素中包含的文字
function text(e) {
    var s = "";
    var e = e.childNodes || e;  //判斷元素是否包含子節點
    for (var i = 0; i < e.length; i ++) {  //遍歷所有子節點
        //通過遞回遍歷所有元素的子節點
        s += e[i].nodeType != 1 ? e[i].nodeValue : text(e[i].childNodes);
    }
    return s;
}
在上面函數中,通過遞回函數檢索指定元素的所有子節點,然後判斷每個子節點的型別,如果不是元素,則讀取該節點的值,否則繼續遞回遍歷該元素包含的所有子節點。

下面使用上面定義的通用方法讀取 div 元素包含的所有文字資訊。
<div id="div1">
    <span class="red">div</span>
    元素
</div>
<script>
    var div = document.getElementById("div1");
    var s = text(div);  //呼叫讀取元素的文字通用方法
    console.log(s);  //返回字串“div 元素”
</script>
這個通用方法不僅可以在 HTML DOM 中使用,也可以在 XML DOM 文件中工作,並相容不同的瀏覽器。

讀取 HTML 字串

使用元素的 innerHTML 屬性可以返回撥用元素包含的所有子節點對應的 HTML 標記字串。最初它是 IE 的私有屬性,HTML 5 規範了 innerHTML 的使用,並得到所有瀏覽器的支援。

範例

下面範例使用 innerHTML 屬性讀取 div 元素包含的 HTML 字串。
<div id="div1">
    <style type="text/css">p {color : red;}</style>
    <p><span>div</span>元素</p>
</div>
<script>
    var div = document.getElementById("div1");
    var s = div.innerHTML;
    console.log(s);
</script>

插入 HTML 字串

使用 innerHTML 屬性可以根據傳入的 HTML 字串,建立新的 DOM 片段,然後用這個 DOM 片段完全替換呼叫元素原有的所有子節點。設定 innerHTML 屬性值之後,可以像存取文件中的其他節點一樣存取新建立的節點。

範例

下面範例將建立一個 1000 行的表格。先構造一個 HTML 字串,然後更新 DOM 的 innerHTML 屬性。
<script>
    function tableInnerHTML () {
        var i, h = ['<table border="1" width="100%">'];
        h.push('<thead>');
        h.push('<tr><th>id</th><th>yes?</th><th>name</th><th>url</th><th>action</th></tr>');
        h.push('</thead>');
        h.push('<tbody>');
        for (i=1;i<=1000;i++) {
            h.push('<tr><td>');
            h.push(i);
            h.push('</td><td>');
            h.push('And the answer is...' + (i % 2 ? 'yes' : 'no'));
            h.push('</td><td>');
            h.push('my name is #' + i);
            h.push('</td><td>');
            h.push('<a href="http://example.org/' + i + '.html">http://example.org/' + i + '.html</a>');
            h.push('</td><td>');
            h.push('<ul>');
            h.push('<li><a href="edit.php?id=' + i + '">edit</a></li>');
            h.push('<li><a href="delete.php?id="' + i + '-id001">delete</a></li>');
            h.push('</ul>');
            h.push('</td>');
            h.push('</tr>');
    }
    h.push('</tbody>');
    h.push('</table>');
    document.getElementById("here").innerHTML = h.join('');
</script>
<div id="here"></div>
<script>
    tableInnerHTML();
</script>
如果通過 DOM 的document.createElement() 和 document.createTextNode() 方法建立同樣的表格,程式碼會非常長。在一個效能苛刻的操作中更新一大塊 HTML 頁面,innerHTML 在大多瀏覽器中執行的更快。

使用 innerHTML 屬性也有一些限制。例如,在大多數瀏覽器中,通過 innerHTML 插入 <script> 標記後,並不會執行其中的指令碼。

替換 HTML 字串

outerHTML 也是 IE 的私有屬性,後來被 HTML 5 規範,與 innerHTML 的功能相同,但是它會包含元素自身。瀏覽器支援狀態:IE 4+、Firefox 8+、Chrome 和 Opera 8+。

範例

下面範例演示了 outerHTML 與 innerHTML 屬性的不同效果。分別為列表結構中不同列表項定義一個滑鼠單擊事件,在事件處理常式中分別使用 outerHTML 和 innerHTML 屬性改變原列表項的 HTML 標記,會發現 outerHTML 是使用 <h2> 替換 <li>,而innerHTML 是把 <h2> 插入到 <li> 中。
<h1>單擊回答問題</h1>
<ul>
    <li>你叫什麼?</li>
    <li>你喜歡 JS 嗎?</li>
</ul>
<script>
    var ul = document.getElementsByTagName("ul")[0];
    var lis = ul.getElementsByTagName("li");
    lis[0].onclick = function () {
        this.innerHTML = "<h2>我叫 C語言中文網</h2>";
    }
    lis[1].onclick = function () {
        this.outerHTML = "<h2>當然喜歡</h2>";
    }
</script>
演示效果如下: