HTML DOM 探索
2017年2月10日20:54:11 CHJ_1993
1、前言
? 因為最近比較忙,好久沒有寫博客了,記得我第一篇自我介紹的博客說經(jīng)常給大家分享一些我學(xué)習(xí)的知識,但是時間過去這么久了,也沒有更新幾篇本章,可能剛開始寫的文章也很爛。作為博客新手,希望大家原諒一下。
? 今天有點時間, 我就來跟大家探討一下 HTML DOM 的一些知識。好了下面開始正文.....
2、DOM的概念
DOM 是 (Document Object Model) 的縮寫
- DOM 是針對 XML 和 HTML 文檔的一個 api (應(yīng)用程序接口)
- DOM 中描述了一個層級化的節(jié)點樹
- DOM 中允許開發(fā)人員對頁面的某一部分內(nèi)容進行修改,移除,添加
W3C 中 DOM標(biāo)準(zhǔn)化分類分成三種:
- 核心 DOM ==== 針對任何結(jié)構(gòu)化文檔的標(biāo)準(zhǔn)模型
- XML DOM ==== 針對XML文檔的標(biāo)準(zhǔn)模板
- HTML DOM ==== 針對HTML 文檔的標(biāo)準(zhǔn)模板
DOM標(biāo)準(zhǔn)分化分為三種,那么前面兩種我們今天不進行探索,我們今天主要來了解的是HTML DOM
3、HTML DOM 的探索
3.1 什么是HTML DOM ?
HTML DOM 是HTML的標(biāo)準(zhǔn)對象模型,也是HTML的標(biāo)準(zhǔn)編程接口
HTML DOM 定義了所有HTML元素的對象 ** 和 屬性,以及訪問他們的方法**
換句話說, HTML DOM 是關(guān)于如何獲取、修改、添加或者刪除HTML元素的標(biāo)準(zhǔn)
3.2 HTML DOM的節(jié)點
根據(jù)W3C(萬維網(wǎng)) 的HTML DOM標(biāo)準(zhǔn),HTML文檔中所有的內(nèi)容都是節(jié)點
- 整個文檔 是一個文檔節(jié)點
- 每個HTML元素都是元素節(jié)點
- HTML 元素內(nèi)的文本是文本節(jié)點
- 每個 HTML 屬性是屬性節(jié)點
- 注釋是注釋節(jié)點
下面我們引用網(wǎng)上的一張圖來描述一下: (HTML DOM 的節(jié)點樹結(jié)構(gòu))
3.2.1 HTML DOM 節(jié)點分類
HTML DOM 中個一共存在12 個節(jié)點類型,任何一個節(jié)點類型都屬于這12個節(jié)點類型之一
如下表:
| 屬性名稱 | 代表中文含義 |
|---|---|
| Node.ELEMENT_NODE | 元素 |
| Node.ATTRIBUTE_NODE | 元素中的屬性 |
| Node.TEXT_NODE | 純文本(沒有子節(jié)點) |
| Node.CDATA_SECTION_NODE | 子節(jié)點是TextNode |
| Node.ENTITY_REFERENCE_NODE | 文檔中的實體引用 |
| Node.ENTITY_NODE | DTD中的實體定義 |
| Node.PROCESSING_INSTRUCTION_NODE | 一個文檔處理程序中使用的特有指令 |
| Node.COMMENT_NODE | 注釋 |
| Node.DOCUMENT_NODE | 最外層的 (根節(jié)點) |
| Node.DOCUMENT_TYPE_NODE | 文檔類型定義 |
| Node.DOCUMENT_FRAGMENT_NODE | 更小型的Docment 的節(jié)點,定義整個數(shù)據(jù)類型主要是為了方便只希望提取文檔的某一部分時使用 |
| Node.NOTATION_NODE | DTD 的Nation定義 |
3.2.2 HTML DOM 文檔節(jié)點的屬性
文檔節(jié)點的屬性,我們今天主要認識的就只有三個:
-
nodeName
節(jié)點名稱,只讀
-
nodeValue
節(jié)點的值 ,可讀可寫
-
nodeType
節(jié)點的類型,只讀
3.3 HTML DOM 核心對象 document 對象
在JavaScript中 是通過Document 來表示文檔的,Document 的屬性如下:
- document的節(jié)點類型 (nodeType) 為 9
- document 的節(jié)點名稱 (nodeName) 是 #document
- document 的節(jié)點值(nodeValue) 為空(null)
- document 是沒有父節(jié)點(parentNode) 的
- document 也沒有根元素(ownerDocument)
3.3.1 通過document 來獲取 元素(節(jié)點)
在JavaScript 獲取元素的方式主要有以下中方法
- document.getElementById() 通過ID的方式來獲取元素.
- document.getElementsByTagName() 根據(jù)標(biāo)簽名來獲取元素
- document.getElementsByName() 通過標(biāo)簽的name屬性的值來獲取元素
- document.getElementsByClassName() 通過class 的屬性值來獲取元素
- querySelector() 通過選擇器名稱來獲取元素(獲取匹配到的第一個)
- querySelectorAll() 通過選擇器名稱來獲取元素(獲取全部)
3.3.1.1 document.getElementById()
通過元素中ID屬性的屬性值來查找元素
語法: node.getElementById("id");
注意:
- 使用該方法不能同時查找多個ID
- 如果有HTML中有相同ID,則只會返回一個元素
- 在 低于 IE 8 版本的IE瀏覽器中,對匹配元素的ID,該方法不區(qū)分大小寫
代碼示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<h1 id="h1">我是標(biāo)題</h1>
</body>
<script type="text/javascript">
var eH1 = document.getElementById("h1");
alert(eH1.innerHTML);
</script>
</html>
3.3.1.2 document.getElementsByTagName()
根據(jù)標(biāo)簽名來獲取元素
語法: node.getElementsByTagName(標(biāo)簽名稱)
返回值: 返回多個同標(biāo)簽名的Element組成的集合
代碼示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<h1 id="myH1" class="myH1class">我是H1標(biāo)簽</h1>
<h1 id="myH2" class="myH1class">我是H1標(biāo)簽</h1>
<h1 id="myH3" class="myH1class">我是H1標(biāo)簽</h1>
<h1 id="myH4" class="myH1class">我是H1標(biāo)簽</h1>
</body>
<script>
var h1_ls = document.getElementsByTagName("h1");
console.log(h1_ls);
for (var i = 0; i < h1_ls.length; i++) {
console.log(h1_ls[i].id); //元素的ID
console.log(h1_ls.item(i).id); //通過元素的Item 來獲取Item內(nèi)容
}
</script>
</html>
3.3.1.3 document.getElementsByName()
通過標(biāo)簽的name屬性的值來獲取元素,可能出現(xiàn)
語法: docuemnt.getElementsByName("name屬性值");
返回值: 返回多個相同的name值的Element組成的集合
注意: 該方法存在嚴(yán)重的兼容性問題,在IE中,此方法還能獲取ID屬性匹配的值
代碼示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<form action="" method="get">
<input type="checkbox" name="input_name" value="洗澡" />洗澡
<input type="checkbox" name="input_name" value="喝水" />喝水
</form>
</body>
<script type="text/javascript">
var names = document.getElementsByName('input_name');
for (var i = 0; i<names.length; i++) {
console.log(names[i].value);
}
</script>
</html>
3.3.1.4 document.getElementsByClassName()
通過相同的class屬性的值來獲取元素
語法: document.getElementsByClassName(class屬性值);
返回值: 返回多個相同的class屬性值的Element組成的集合
代碼示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<h1 id="myH1" class="myH1class">我是H1標(biāo)簽</h1>
<h2 id="myH2" class="myH1class">我是H2標(biāo)簽</h1>
<h3 id="myH3" class="myH1class">我是H3標(biāo)簽</h1>
<h4 id="myH4" class="myH1class">我是H4標(biāo)簽</h1>
</body>
<script type="text/javascript">
var myClassLi = document.getElementsByClassName('myH1class');
for (var i = 0; i<myClassLi.length; i++) {
console.log(myClassLi[i].value);
}
</script>
</html>
3.3.1.4 querySelector()
通過CSS 選擇器的放來來獲取元素,
指定一個或者多個匹配的CSS選擇器,id,class, 類型,屬性
如果針對多個選擇器,中間使用d"逗號分隔",
語法: document.querySelector("#demo")
返回值: 直接返回匹配到的第一個元素,如果沒有找到則返回null
代碼示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<p id="demo"></p>
</body>
<script type="text/javascript">
var p_1 = document.querySelector("#demo");
console.log(p_1);
</script>
</html>
3.3.1.4 querySelectorAll()
HTML5引入的一種新的查找元素的方法
語法: document.querySelectorAll(".p_1")
返回值: 返回查找到的所有相同選擇器的Element 集合
注意: 該方法不是實時返回的,只有調(diào)用的時候才會返回,因為這樣開發(fā)人員通??梢岳脗晤愡x擇器( :hover , :visited ) 去訪問用戶的瀏覽習(xí)慣等,所以現(xiàn)在很多瀏覽器不支持該方法
代碼示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div class="p_1"></div>
<div class="p_1"></div>
<div class="p_1"></div>
</body>
<script type="text/javascript">
var all = document.querySelectorAll(".p_1");
console.log(all)
</script>
</html>
好了,說了上面一大推,篇幅有點長了,但是我覺得我還是要繼續(xù)把下面幾點說完
上面說了元素的獲取的幾種方法,那么現(xiàn)在我們可以獲取到元素了,那么元素和元素之間的關(guān)系又是怎么樣的? 那么下面我們來說 元素節(jié)點之間的關(guān)系
3.3.2 HTML DOM 中節(jié)點的關(guān)系
我們學(xué)過HTML 的都知道 HTML元素之間的關(guān)系 有父子關(guān)系,和兄弟關(guān)系(同級元素)
那么在DOM中節(jié)點關(guān)系有以下幾種
- parent 父節(jié)點
- child子節(jié)點
- sibling 兄弟節(jié)點(同級節(jié)點)
- root 根節(jié)點
如圖所示:
-
父節(jié)點屬性(parentNode)
獲取一個元素的父節(jié)點
語法:
node.parentNode -
兄弟節(jié)點屬性(sibling)
同級節(jié)點屬性又分為兩個小的屬性:
? 上一個同級節(jié)點(previousSibling)
? 獲取某個元素的上一個同級節(jié)點
? 語法:
node.previousSibling? 下一個同級節(jié)點(nextSibling)
? 獲取某個元素的下一個同級節(jié)點
? 語法
node.nextSibling因為在使用者兩種方法獲取到,可能含有
<div> </div>中間的空格,又因為JavaScript 是一種弱類型語言,就衍生了下面的兩種方法:? 上一個同級元素(previousElementSibling)
? 獲取某個元素的上一個同級元素
? 語法:
node.previousElementSibling? 下一個同級元素(nextElementSibling)
? 獲取某個元素的下一個同級元素
? 語法
node.nextElementSibling -
根節(jié)點 ( ownerDocument)
獲取某個元素的根元素
語法:
node.ownerDocument獲取一個元素的根節(jié)點
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="demo">
<a href="###">搜狐</a><div id="div">DIV</div><div>
<a href="#"></a>
</div>
<input type="text" />
</div>
</body>
<script type="text/javascript">
//parentNode 獲取父節(jié)點
var div = document.getElementById("demo");
div.previousSibling;
console.log(div.parentNode.nodeName); //BODY
//previousSibling 獲取元素的上一個同級節(jié)點
var div1 = document.getElementById("div");
var preSib= div1.previousSibling;
console.log(preSib);
//previousElementSibling 獲取元素的上一個同級節(jié)點
var preSib2= div1.previousElementSibling;
console.log(preSib2);
//nextSibling 獲取元素的下一個同級節(jié)點
var nextElement = div1.nextSibling;
console.log(nextElement)
//nextElementSibling 獲取元素的下一個同級節(jié)點
var nextElement2 = div1.nextElementSibling;
console.log(nextElement2)
//ownerDocument 獲取元素的根節(jié)點
var rootElement = div1.ownerDocument;
console.log(rootElement)
</script>
</html>
-
子節(jié)點屬性(ChildNodes)
在這里要寫的是三個小屬性
? 所有子節(jié)點(ChildNodes)
? 用來獲取一個元素的所有子節(jié)點
? 返回值: 一個數(shù)組,只獲取子節(jié)點,不能獲取子節(jié)點的子節(jié)點
? 語法:
node.chilNodes? 第一個子節(jié)點(firstChild)
? 獲取元素的第一個子節(jié)點 ,如果匹配不到則返回null
? 語法:
node.firstChild? 最后一個子節(jié)點(lastChild)
? 獲取元素的最后一個子節(jié)點 ,如果匹配不到則返回null
? 語法
node.lastChild因為在使用者兩種方法獲取到,可能含有
<div> </div>中間的空格,又因為JavaScript 是一種弱類型語言,就衍生了下面的兩種方法:? 第一個子元素(firstElementChild)
? 獲取某個元素的第一個子元素
? 語法:
node.firstElementChild? 最后一個子元素(lastElementChild)
? 獲取某個元素的最后一個子元素
? 語法
node.lastElementChild代碼:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <div id="demo"> <a href="###">簡書</a> <a href="###">百度</a> <div> <a href="###">博客</a> </div> <input type="text" name="input_name" id="input" value="" /> </div> </body> <script type="text/javascript"> //獲取元素的所有子節(jié)點 var nodes = document.getElementById("demo").childNodes; console.log(nodes); for (var i = 0;i<nodes.length; i++) { console.log(nodes[i].nodeName); } //獲取所有子元素的個數(shù) var nodes = document.getElementById("demo").childElementCount; console.log(nodes); //firstChild 獲取元素的第一個子節(jié)點 var div = document.getElementById("demo"); var firstChlid = div.firstChild; console.log(firstChild); console.log(firstChild.nodeName); //firstElementChild 獲取元素的第一個子節(jié)點 var firstChild2 = div.firstElementChild; console.log(firstChild2); console.log(firstChild2.nodeName); //firstChild 獲取元素的第一個子節(jié)點 var div = document.getElementById("demo"); var lastCh = div.lastChild; console.log(lastCh); console.log(lastCh.nodeName); //firstElementChild 獲取元素的第一個子節(jié)點 var lastChild = div.lastElementChild; console.log(lastChild); console.log(lastChild.nodeName); </script> </html>?
有比比了好久,說了那么多的元素之間的關(guān)系,那么我們平時獲取元素,不僅僅只是想獲取到他的一下屬性,了解他的關(guān)系吧,同樣我們有事需要對元素進行操作,那么下面我們來說說對Node節(jié)點的操作
3.3.2 HTML DOM 中節(jié)點增加 刪除 修改 創(chuàng)建
由于文章篇幅比較長了,大家也是不想看到我說一大推的廢話了 那么我下面直接貼出代碼 給大家看 在代碼中我也是注釋的比較清楚,以后再來修改
代碼如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="demo">
</div>
<ul id="language">
<li>Java</li>
<li>C#</li>
</ul>
<button onclick="addNode()">點擊添加一個新的首節(jié)點</button>
<button onclick="removeNode()">刪除一個子節(jié)點</button>
<button onclick="replaceNode()">替換首節(jié)點</button>
<button onclick="cloneNodes()">克隆整個列表</button>
</body>
<script type="text/javascript">
/*
修改
* 1.創(chuàng)建文本節(jié)點
* createTextNode(text)
* 參數(shù): text 文本
* 返回值: 創(chuàng)建的文本標(biāo)簽
* 該方法屬于 document 的
* 2.添加一個子節(jié)點
* addpendChild(node)
* 參數(shù):
* node: 必選參數(shù),需要添加的節(jié)點
* 返回值: 參數(shù)對象本身
* 翻譯過來時追加,如果本身已經(jīng)有child ,則追加到child之后
* 添加進去就是 lastChild
* 3.創(chuàng)建新的元素節(jié)點
* createElement(nodeName)
* 參數(shù):
* nodeName: 需要創(chuàng)建的元素名稱
* 返回值: 創(chuàng)建的元素節(jié)點
* 4.在節(jié)點之前加入新的節(jié)點
* insertBefor(newNode,existingNode)
* 參數(shù):
* newNode:需要插入的新節(jié)點
* existingNode: 當(dāng)前插入的目標(biāo)節(jié)點
* 會將新節(jié)點插入到目標(biāo)節(jié)點之前
* 5.移除一個子節(jié)點
* removeChild(node)
* 參數(shù):
* node:必選參數(shù),表示需要移除的子節(jié)點
* 6.替換一個子節(jié)點
* replaceChild(newNode,oldNode)
* 參數(shù):
* newNode: 新節(jié)點
* oldNode: 舊的節(jié)點
* 7.克隆節(jié)點
* 該方法用于創(chuàng)建指定的節(jié)點的精準(zhǔn)拷貝所有的屬性和屬性值
* cloneNode(deep)
* 參數(shù):
* deep: true/ false
* true: 將遞歸復(fù)制當(dāng)前節(jié)點的所有節(jié)點
* false: 只復(fù)制當(dāng)前節(jié)點
*/
var divDemo = document.getElementById("demo");
//======創(chuàng)建一個文本節(jié)點====
var textNode = document.createTextNode("hello world");
console.log(textNode.nodeName); // #text
console.log(textNode.nodeValue); // hello world
//=====添加一個文本節(jié)點===
var appendNode = divDemo.appendChild(textNode);
console.log(appendNode.nodeValue); //hello world
//===== 創(chuàng)建元素節(jié)點====
var newElement = document.createElement("a");
var newElementText = document.createTextNode("新建的元素內(nèi)容");
newElement.appendChild(newElementText);
var divDemo = divDemo.appendChild(newElement);
//====在節(jié)點之前加入新的節(jié)點===
function addNode(){
var newItem = document.createElement("li"); //創(chuàng)建一個新的li元素
var newItemTextNode = document.createTextNode("Javascript");
newItem.appendChild(newItemTextNode);
var languageList = document.getElementById("language");
//將新創(chuàng)建的Item添加到目標(biāo)節(jié)點之前
languageList.insertBefore(newItem,languageList.firstChild);
}
//=======移除子節(jié)點====
function removeNode(){
var languageList = document.getElementById("language");
var li_lsit = languageList.getElementsByTagName("li");
//移除li中的第一個
languageList.removeChild(li_lsit[0]);
}
//============替換子節(jié)點=====
function replaceNode(){
var languageList = document.getElementById("language");
var newLi = document.createElement("li");
newLi.innerHTML="node.js"
console.log(newLi.value);
languageList.replaceChild(newLi,languageList.firstElementChild);
}
//==========克隆節(jié)點===========
function cloneNodes(){
var languageList = document.getElementById("language");
var newList = languageList.cloneNode(false);
document.getElementsByTagName("body")[0].appendChild(newList);
}
</script>
</html>
好了 看到這里 我的文章也就結(jié)束了,感謝您的瀏覽!
你們的支持,就是我前進的動力