Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
OM 節(jié)點(diǎn)
根據(jù) W3C 的 HTML DOM 標(biāo)準(zhǔn),HTML 文檔中的所有內(nèi)容都是節(jié)點(diǎn):
整個(gè)文檔是一個(gè)文檔節(jié)點(diǎn)
每個(gè) HTML 元素是元素節(jié)點(diǎn)
HTML 元素內(nèi)的文本是文本節(jié)點(diǎn)
每個(gè) HTML 屬性是屬性節(jié)點(diǎn)
注釋是注釋節(jié)點(diǎn)
HTML DOM 節(jié)點(diǎn)樹
HTML DOM 將 HTML 文檔視作樹結(jié)構(gòu)。這種結(jié)構(gòu)被稱為節(jié)點(diǎn)樹:
HTML DOM Tree 實(shí)例
通過 HTML DOM,樹中的所有節(jié)點(diǎn)均可通過 JavaScript 進(jìn)行訪問。所有 HTML 元素(節(jié)點(diǎn))均可被修改,也可以創(chuàng)建或刪除節(jié)點(diǎn)。
節(jié)點(diǎn)父、子和同胞
節(jié)點(diǎn)樹中的節(jié)點(diǎn)彼此擁有層級(jí)關(guān)系。
父(parent)、子(child)和同胞(sibling)等術(shù)語用于描述這些關(guān)系。父節(jié)點(diǎn)擁有子節(jié)點(diǎn)。同級(jí)的子節(jié)點(diǎn)被稱為同胞(兄弟或姐妹)。
在節(jié)點(diǎn)樹中,頂端節(jié)點(diǎn)被稱為根(root)
每個(gè)節(jié)點(diǎn)都有父節(jié)點(diǎn)、除了根(它沒有父節(jié)點(diǎn))
一個(gè)節(jié)點(diǎn)可擁有任意數(shù)量的子
同胞是擁有相同父節(jié)點(diǎn)的節(jié)點(diǎn)
下面的圖片展示了節(jié)點(diǎn)樹的一部分,以及節(jié)點(diǎn)之間的關(guān)系:
請(qǐng)看下面的 HTML 片段:
<html>
<head>
<title>DOM 教程</title>
</head>
<body>
<h1>DOM 第一課</h1>
<p>Hello world!</p>
</body>
</html>
并且:
并且:
警告!
DOM 處理中的常見錯(cuò)誤是希望元素節(jié)點(diǎn)包含文本。
在本例中:<title>DOM 教程</title>,元素節(jié)點(diǎn) <title>,包含值為 "DOM 教程" 的文本節(jié)點(diǎn)。
可通過節(jié)點(diǎn)的 innerHTML 屬性來訪問文本節(jié)點(diǎn)的值。
義
樹是一種數(shù)據(jù)結(jié)構(gòu),由一組表示分層樹結(jié)構(gòu)的鏈接節(jié)點(diǎn)組成。每個(gè)節(jié)點(diǎn)都通過父子關(guān)系鏈接到其他節(jié)點(diǎn)。樹中的第一個(gè)節(jié)點(diǎn)是根,而沒有任何子節(jié)點(diǎn)的節(jié)點(diǎn)是葉子。
JavaScript 樹可視化
樹數(shù)據(jù)結(jié)構(gòu)中的每個(gè)節(jié)點(diǎn)都必須具有以下屬性:
key: 節(jié)點(diǎn)的鍵
value: 節(jié)點(diǎn)的值
parent: 節(jié)點(diǎn)的父節(jié)點(diǎn)(null如果沒有)
children: 指向節(jié)點(diǎn)子節(jié)點(diǎn)的指針數(shù)組
樹形數(shù)據(jù)結(jié)構(gòu)的主要操作有:
insert: 插入一個(gè)節(jié)點(diǎn)作為給定父節(jié)點(diǎn)的子節(jié)點(diǎn)
remove: 從樹中刪除一個(gè)節(jié)點(diǎn)及其子節(jié)點(diǎn)
find: 檢索給定節(jié)點(diǎn)
preOrderTraversal: 通過遞歸遍歷每個(gè)節(jié)點(diǎn)及其子節(jié)點(diǎn)來遍歷樹
postOrderTraversal: 通過遞歸遍歷每個(gè)節(jié)點(diǎn)的子節(jié)點(diǎn)來遍歷樹
class TreeNode {
constructor(key, value = key, parent = null) {
this.key = key;
this.value = value;
this.parent = parent;
this.children = [];
}
get isLeaf() {
return this.children.length === 0;
}
get hasChildren() {
return !this.isLeaf;
}
}
class Tree {
constructor(key, value = key) {
this.root = new TreeNode(key, value);
}
*preOrderTraversal(node = this.root) {
yield node;
if (node.children.length) {
for (let child of node.children) {
yield* this.preOrderTraversal(child);
}
}
}
*postOrderTraversal(node = this.root) {
if (node.children.length) {
for (let child of node.children) {
yield* this.postOrderTraversal(child);
}
}
yield node;
}
insert(parentNodeKey, key, value = key) {
for (let node of this.preOrderTraversal()) {
if (node.key === parentNodeKey) {
node.children.push(new TreeNode(key, value, node));
return true;
}
}
return false;
}
remove(key) {
for (let node of this.preOrderTraversal()) {
const filtered = node.children.filter(c => c.key !== key);
if (filtered.length !== node.children.length) {
node.children = filtered;
return true;
}
}
return false;
}
find(key) {
for (let node of this.preOrderTraversal()) {
if (node.key === key) return node;
}
return undefined;
}
}
用class創(chuàng)建一個(gè)類TreeNode,使用構(gòu)造函數(shù)初始化 key, value, parent 和 children。
定義一個(gè)isLeaf getter方法,用Array.prototype.length檢查children是否為空。
定義一個(gè)hasChildren getter方法,用來檢查是否有子節(jié)點(diǎn)。
用 class 創(chuàng)建一個(gè)Tree,使用構(gòu)造函數(shù)初始化樹的根節(jié)點(diǎn)。
定義一個(gè)preOrderTraversal() 方法,按順序遍歷樹的生成器方法,使用 yield* 語法將遍歷委托給自身。
定義一個(gè)postOrderTraversal()方法,以后序遍歷樹的生成器方法,使用yield*語法將遍歷委托給自身。
定義一個(gè)insert()方法,使用preOrderTraversal()和Array.prototype.push()方法向樹中添加一個(gè)TreeNode 節(jié)點(diǎn)。
定義一個(gè)remove()方法,使用preOrderTraversal()和Array.prototype.filter()方法從樹刪除一個(gè)TreeNode節(jié)點(diǎn)。
定義一個(gè)find()方法,使用preOrderTraversal()方法檢索樹中的給定節(jié)點(diǎn)。
const tree = new Tree(1, 'AB');
tree.insert(1, 11, 'AC');
tree.insert(1, 12, 'BC');
tree.insert(12, 121, 'BG');
[...tree.preOrderTraversal()].map(x => x.value);
// ['AB', 'AC', 'BC', 'BCG']
tree.root.value; // 'AB'
tree.root.hasChildren; // true
tree.find(12).isLeaf; // false
tree.find(121).isLeaf; // true
tree.find(121).parent.value; // 'BC'
tree.remove(12);
[...tree.postOrderTraversal()].map(x => x.value);
// ['AC', 'AB']
過 HTML DOM,您能夠使用節(jié)點(diǎn)關(guān)系在節(jié)點(diǎn)樹中導(dǎo)航。
HTML DOM 節(jié)點(diǎn)列表
getElementsByTagName() 方法返回節(jié)點(diǎn)列表。節(jié)點(diǎn)列表是一個(gè)節(jié)點(diǎn)數(shù)組。
下面的代碼選取文檔中的所有 <p> 節(jié)點(diǎn):
實(shí)例
varx=document.getElementsByTagName("p");
可以通過下標(biāo)號(hào)訪問這些節(jié)點(diǎn)。如需訪問第二個(gè) <p>,您可以這么寫:
y=x[1];
嘗試一下 ?
注意:
下標(biāo)號(hào)從 0 開始。
HTML DOM 節(jié)點(diǎn)列表長度
length 屬性定義節(jié)點(diǎn)列表中節(jié)點(diǎn)的數(shù)量。
您可以使用 length 屬性來循環(huán)節(jié)點(diǎn)列表:
實(shí)例
x=document.getElementsByTagName("p");for(i=0;i<x.length;i++){document.write(x[i].innerHTML); document.write("<br>");}
實(shí)例解析:
獲取所有 <p> 元素節(jié)點(diǎn)
輸出每個(gè) <p> 元素的文本節(jié)點(diǎn)的值
導(dǎo)航節(jié)點(diǎn)關(guān)系
您能夠使用三個(gè)節(jié)點(diǎn)屬性:parentNode、firstChild 以及 lastChild ,在文檔結(jié)構(gòu)中進(jìn)行導(dǎo)航。
請(qǐng)看下面的 HTML 片段:
<html><head><metacharset="utf-8"></head><body><p>Hello World!</p><div><p>DOM 是非常有用的!</p><p>這個(gè)實(shí)例演示了節(jié)點(diǎn)的關(guān)系。</p></div></body></html>
首個(gè) <p> 元素是 <body> 元素的首個(gè)子元素(firstChild)
<div> 元素是 <body> 元素的最后一個(gè)子元素(lastChild)
<body> 元素是首個(gè) <p> 元素和 <div> 元素的父節(jié)點(diǎn)(parentNode)
firstChild 屬性可用于訪問元素的文本:
實(shí)例
<pid="intro">Hello World!</p><script>x=document.getElementById("intro");document.write(x.firstChild.nodeValue);</script>
嘗試一下 ?
DOM 根節(jié)點(diǎn)
這里有兩個(gè)特殊的屬性,可以訪問全部文檔:
document.documentElement - 全部文檔
document.body - 文檔的主體
實(shí)例
<p>Hello World!</p><div><p>DOM 是非常有用的!</p><p>這個(gè)實(shí)例演示了 <b>document.body</b> 屬性。</p></div><script>alert(document.body.innerHTML);</script>
嘗試一下 ?
childNodes 和 nodeValue
除了 innerHTML 屬性,您也可以使用 childNodes 和 nodeValue 屬性來獲取元素的內(nèi)容。
下面的代碼獲取 id="intro" 的 <p> 元素的值:
實(shí)例
<pid="intro">Hello World!</p><script>txt=document.getElementById("intro").childNodes[0].nodeValue;document.write(txt);</script>
嘗試一下 ?
在上面的例子中,getElementById 是一個(gè)方法,而 childNodes 和 nodeValue 是屬性。
*請(qǐng)認(rèn)真填寫需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。