原文 鏈接
一伦糯、基本類型介紹
1.1 Node類型
-
DOM1
級定義了一個Node
接口建椰,該接口由DOM
中所有節(jié)點類型實現(xiàn)硝桩。這個Node
接口在JS
中是作為Node
類型實現(xiàn)的勾笆。在IE9
以下版本無法訪問到這個類型梧宫,JS
中所有節(jié)點都繼承自Node
類型橡类,都共享著相同的基本屬性和方法 -
Node
有一個屬性nodeType
表示Node
的類型蛇尚,它是一個整數(shù),其數(shù)值分別表示相應(yīng)的Node
類型
- 假設(shè)我們要判斷一個
Node
是不是元素顾画,我們可以這樣判斷
if(someNode.nodeType == 1){
console.log("Node is a element");
}
- 這些
Node
類型中取劫,我們最常用的就是element
匆笤,text
,attribute
谱邪,comment
炮捧,document
,document_fragment
這幾種類型
1.2 Element類型
Element
提供了對元素標簽名惦银,子節(jié)點和特性的訪問咆课,我們常用HTML
元素比如div
,span
,a
等標簽就是element
中的一種。-
Element
有下面幾條特性:-
nodeType
為1
-
nodeName
為元素標簽名蟀俊,tagName
也是返回標簽名 -
nodeValue
為null
-
parentNode
可能是Document
或Element
- 子節(jié)點可能是
Element
,Text
殊校,Comment
,Processing_Instruction
读存,CDATASection
或EntityReference
-
1.3 Text類型
-
Text
表示文本節(jié)點为流,它包含的是純文本內(nèi)容,不能包含html
代碼让簿,但可以包含轉(zhuǎn)義后的html
代碼敬察。Text
有下面的特性:-
nodeType
為3
-
nodeName
為#text
-
nodeValue
為文本內(nèi)容 -
parentNode
是一個Element
- 沒有子節(jié)點
-
1.4 Attr類型
-
Attr
類型表示元素的特性,相當于元素的attributes
屬性中的節(jié)點尔当,它有下面的特性:-
nodeType
值為2 -
nodeName
是特性的名稱 -
nodeValue
是特性的值 -
parentNode
為null
-
1.5 Comment類型
-
Comment
表示HTML
文檔中的注釋静汤,它有下面的幾種特征:-
nodeType
為8 -
nodeName
為#comment
-
nodeValue
為注釋的內(nèi)容 -
parentNode
可能是Document
或Element
- 沒有子節(jié)點
-
1.6 Document
-
Document
表示文檔,在瀏覽器中居凶,document
對象是HTMLDocument
的一個實例,表示整個頁面藤抡,它同時也是window
對象的一個屬性侠碧。Document
有下面的特性:-
nodeType
為9
-
nodeName
為#document
-
nodeValue
為null
-
parentNode
為null
- 子節(jié)點可能是一個
DocumentType
或Element
-
1.7 DocumentFragment類型
-
DocumentFragment
是所有節(jié)點中唯一一個沒有對應(yīng)標記的類型,它表示一種輕量級的文檔缠黍,可能當作一個臨時的倉庫用來保存可能會添加到文檔中的節(jié)點弄兜。DocumentFragment
有下面的特性:-
nodeType
為11
-
nodeName
為#document-fragment
-
nodeValue
為null
-
parentNode
為null
-
我們簡單地介紹了幾種常見的
Node
類型,要記住瓷式,HTML
中的節(jié)點并不只是包括元素節(jié)點替饿,它還包括文本節(jié)點,注釋節(jié)點等等贸典。在這里我們只是簡單地說明了幾種常見的節(jié)點.
二视卢、 DOM提供的幾個屬性
2.1 childNodes屬性
- 在一棵節(jié)點樹上,
childNodes
屬性可以用來獲取任何一個元素的所有子節(jié)點廊驼,它是一個包含這個元素全部子元素的數(shù)組
element.childNodes
2.2 nodeType屬性
- 節(jié)點之間的關(guān)系構(gòu)成了節(jié)點層次据过,
html
頁面的可以畫出一個以html
標簽為根節(jié)點的樹形結(jié)構(gòu)
DOM
會把文檔看作是一棵樹惋砂,同時定義了很多方法來操作這棵數(shù)中的每一個元素(節(jié)點)
<html lang="en">
<head>
<title>Document</title>
</head>
<body>
<p>hello world!!!</p>
</body>
</html>
[圖片上傳失敗...(image-635720-1545535313683)]
- 每一個節(jié)點都有
nodeType
屬性
node.nodeType
-
nodeType
屬性總共有12中可能取值,但其中僅有3種有實用價值- 元素節(jié)點的
nodeType
屬性值是1 - 屬性節(jié)點的
nodeType
屬性值是2 - 文本節(jié)點的
nodeType
屬性值是3
- 元素節(jié)點的
description.firstChild.nodeValue = text;
2.3 nodeValue屬性
-
nodeValue
屬性- 如果想改變一個文本節(jié)點的值绳锅,那就使用
DOM
提供的nodeValue
,它用來得到一個節(jié)點的值node.nodeValue
- 需要注意:
nodeValue
屬性獲取對象的值時西饵,得到的并不是包含在這個段落里的文本 - nodeValue屬性不僅可以用來檢測節(jié)點的值,還可以設(shè)置節(jié)點的值
- 如果想改變一個文本節(jié)點的值绳锅,那就使用
2.4 firstChild和lastChild屬性
- 數(shù)組元素
childNodes[0]
有個更直觀的同義詞鳞芙。無論如何眷柔,只要訪問childNodes
數(shù)組的第一個元素,都可以把它寫成firstChild
node.firstChild
與下面等價
node.childNodes[0]
-
DOM
還提供了一個與之對應(yīng)的lastChild
屬性
node.lastChild
三原朝、節(jié)點創(chuàng)建型API
- 在這里驯嘱,我將常用的
DOM
操作api
進行分類,首先要介紹的是創(chuàng)建型的api
竿拆。這一類型的api
宙拉,簡而言之就是用來創(chuàng)建節(jié)點的
3.1 createElement
-
createElement
通過傳入指定的一個標簽名來創(chuàng)建一個元素,如果傳入的標簽名是一個未知的丙笋,則會創(chuàng)建一個自定義的標簽谢澈,注意:IE8
以下瀏覽器不支持自定義標簽
var div = document.createElement("div");
- 使用
createElement
要注意:通過createElement
創(chuàng)建的元素并不屬于html
文檔,它只是創(chuàng)建出來御板,并未添加到html
文檔中锥忿,要調(diào)用appendChild
或insertBefore
等方法將其添加到HTML
文檔樹中
3.2 createTextNode
-
createTextNode
用來創(chuàng)建一個文本節(jié)點,用法如下
var textNode = document.createTextNode("一個TextNode");
-
createTextNode
接收一個參數(shù)怠肋,這個參數(shù)就是文本節(jié)點中的文本敬鬓,和createElement
一樣,創(chuàng)建后的文本節(jié)點也只是獨立的一個節(jié)點笙各,同樣需要appendChild
將其添加到HTML
文檔樹中
3.3 cloneNode
-
cloneNode
是用來返回調(diào)用方法的節(jié)點的一個副本钉答,它接收一個bool
參數(shù),用來表示是否復(fù)制子元素杈抢,使用如下:
var parent = document.getElementById("parentElement");
var parent2 = parent.cloneNode(true);// 傳入true
parent2.id = "parent2";
- 這段代碼通過
cloneNode
復(fù)制了一份parent
元素数尿,其中cloneNode
的參數(shù)為true
,表示parent
的子節(jié)點也被復(fù)制惶楼,如果傳入false
右蹦,則表示只復(fù)制了parent
節(jié)點
<div id="parent">
我是父元素的文本
<br/>
<span>
我是子元素
</span>
</div>
<button id="btnCopy">復(fù)制</button>
var parent = document.getElementById("parent");
document.getElementById("btnCopy").onclick = function(){
var parent2 = parent.cloneNode(true);
parent2.id = "parent2";
document.body.appendChild(parent2);
}
這段代碼很簡單,主要是綁定
button
事件歼捐,事件內(nèi)容是復(fù)制了一個parent
何陆,修改其id
,然后添加到文檔中-
這里有幾點要注意:
- 和
createElement
一樣豹储,cloneNode
創(chuàng)建的節(jié)點只是游離有html
文檔外的節(jié)點贷盲,要調(diào)用appendChild
方法才能添加到文檔樹中 - 如果復(fù)制的元素有
id
,則其副本同樣會包含該id
剥扣,由于id
具有唯一性晃洒,所以在復(fù)制節(jié)點后必須要修改其id - 調(diào)用接收的
bool
參數(shù)最好傳入慨灭,如果不傳入該參數(shù),不同瀏覽器對其默認值的處理可能不同
- 和
-
除此之外球及,我們還有一個需要注意的點:
- 如果被復(fù)制的節(jié)點綁定了事件氧骤,則副本也會跟著綁定該事件嗎?這里要分情況討論:
- 如果是通過
addEventListener
或者比如onclick
進行綁定事件吃引,則副本節(jié)點不會綁定該事件 - 如果是內(nèi)聯(lián)方式綁定比如
- 如果是通過
- 如果被復(fù)制的節(jié)點綁定了事件氧骤,則副本也會跟著綁定該事件嗎?這里要分情況討論:
<div onclick="showParent()"></div>
- 這樣的話筹陵,副本節(jié)點同樣會觸發(fā)事件
3.4 createDocumentFragment
createDocumentFragment
方法用來創(chuàng)建一個DocumentFragment
。在前面我們說到DocumentFragment
表示一種輕量級的文檔镊尺,它的作用主要是存儲臨時的節(jié)點用來準備添加到文檔中createDocumentFragment
方法主要是用于添加大量節(jié)點到文檔中時會使用到朦佩。假設(shè)要循環(huán)一組數(shù)據(jù),然后創(chuàng)建多個節(jié)點添加到文檔中
<ul id="list"></ul>
<input type="button" value="添加多項" id="btnAdd" />
document.getElementById("btnAdd").onclick = function(){
var list = document.getElementById("list");
for(var i = 0;i < 100; i++){
var li = document.createElement("li");
li.textContent = i;
list.appendChild(li);
}
}
這段代碼將按鈕綁定了一個事件庐氮,這個事件創(chuàng)建了100個
li
節(jié)點语稠,然后依次將其添加HTML
文檔中。這樣做有一個缺點:每次一創(chuàng)建一個新的元素弄砍,然后添加到文檔樹中仙畦,這個過程會造成瀏覽器的回流。所謂回流簡單說就是指元素大小和位置會被重新計算音婶,如果添加的元素太多慨畸,會造成性能問題。這個時候衣式,就是使用createDocumentFragment了
DocumentFragment
不是文檔樹的一部分寸士,它是保存在內(nèi)存中的,所以不會造成回流問題碴卧。我們修改上面的代碼如下
document.getElementById("btnAdd").onclick = function(){
var list = document.getElementById("list");
var fragment = document.createDocumentFragment();
for(var i = 0;i < 100; i++){
var li = document.createElement("li");
li.textContent = i;
fragment.appendChild(li);
}
list.appendChild(fragment);
}
- 優(yōu)化后的代碼主要是創(chuàng)建了一個
fragment
弱卡,每次生成的li
節(jié)點先添加到fragment
,最后一次性添加到list
3.5 創(chuàng)建型API總結(jié)
-
創(chuàng)建型
api
主要包括createElement
住册,createTextNode
婶博,cloneNode
和createDocumentFragment
四個方法,需要注意下面幾點:- 它們創(chuàng)建的節(jié)點只是一個孤立的節(jié)點界弧,要通過
appendChild
添加到文檔中 -
cloneNode
要注意如果被復(fù)制的節(jié)點是否包含子節(jié)點以及事件綁定等問題 - 使用
createDocumentFragment
來解決添加大量節(jié)點時的性能問題
- 它們創(chuàng)建的節(jié)點只是一個孤立的節(jié)點界弧,要通過
四、頁面修改型API
- 前面我們提到創(chuàng)建型
api
搭综,它們只是創(chuàng)建節(jié)點垢箕,并沒有真正修改到頁面內(nèi)容,而是要調(diào)用appendChild
來將其添加到文檔樹中兑巾。我在這里將這類會修改到頁面內(nèi)容歸為一類条获。
修改頁面內(nèi)容的api
主要包括:appendChild
,insertBefore
蒋歌,removeChild
帅掘,replaceChild
4.1 appendChild
-
appendChild
我們在前面已經(jīng)用到多次委煤,就是將指定的節(jié)點添加到調(diào)用該方法的節(jié)點的子元素的末尾。調(diào)用方法如下:
parent.appendChild(child);
child
節(jié)點將會作為parent
節(jié)點的最后一個子節(jié)點appendChild
這個方法很簡單修档,但是還有有一點需要注意:如果被添加的節(jié)點是一個頁面中存在的節(jié)點碧绞,則執(zhí)行后這個節(jié)點將會添加到指定位置,其原本所在的位置將移除該節(jié)點吱窝,也就是說不會同時存在兩個該節(jié)點在頁面上讥邻,相當于把這個節(jié)點移動到另一個地方
<div id="child">
要被添加的節(jié)點
</div>
<br/>
<br/>
<br/>
<div id="parent">
要移動的位置
</div>
<input id="btnMove" type="button" value="移動節(jié)點" />
document.getElementById("btnMove").onclick = function(){
var child = document.getElementById("child");
document.getElementById("parent").appendChild(child);
}
- 這段代碼主要是獲取頁面上的
child
節(jié)點,然后添加到指定位置院峡,可以看到原本的child
節(jié)點被移動到parent
中了兴使。
這里還有一個要注意的點:如果child
綁定了事件,被移動時照激,它依然綁定著該事件
4.2 insertBefore
-
insertBefore
用來添加一個節(jié)點到一個參照節(jié)點之前发魄,用法如下
parentNode.insertBefore(newNode,refNode);
-
parentNode
表示新節(jié)點被添加后的父節(jié)點 -
newNode
表示要添加的節(jié)點 -
refNode
表示參照節(jié)點,新節(jié)點會添加到這個節(jié)點之前
<div id="parent">
父節(jié)點
<div id="child">
子元素
</div>
</div>
<input type="button" id="insertNode" value="插入節(jié)點" />
var parent = document.getElementById("parent");
var child = document.getElementById("child");
document.getElementById("insertNode").onclick = function(){
var newNode = document.createElement("div");
newNode.textContent = "新節(jié)點"
parent.insertBefore(newNode,child);
}
這段代碼創(chuàng)建了一個新節(jié)點俩垃,然后添加到
child
節(jié)點之前和
appendChild
一樣励幼,如果插入的節(jié)點是頁面上的節(jié)點,則會移動該節(jié)點到指定位置吆寨,并且保留其綁定的事件赏淌。-
關(guān)于第二個參數(shù)參照節(jié)點還有幾個注意的地方:
-
refNode
是必傳的,如果不傳該參數(shù)會報錯 - 如果
refNode
是undefined
或null
啄清,則insertBefore
會將節(jié)點添加到子元素的末尾
-
4.3 removeChild
-
removeChild
顧名思義六水,就是刪除指定的子節(jié)點并返回,用法如下
var deletedChild = parent.removeChild(node);
deletedChild
指向被刪除節(jié)點的引用辣卒,它等于node
掷贾,被刪除的節(jié)點仍然存在于內(nèi)存中,可以對其進行下一步操作荣茫。注意:如果被刪除的節(jié)點不是其子節(jié)點想帅,則程序?qū)箦e。我們可以通過下面的方式來確狈壤颍可以刪除:
if(node.parentNode){
node.parentNode.removeChild(node);
}
- 通過節(jié)點自己獲取節(jié)點的父節(jié)點港准,然后將自身刪除
4.4 replaceChild
-
replaceChild
用于使用一個節(jié)點替換另一個節(jié)點,用法如下
parent.replaceChild(newChild,oldChild);
-
newChild
是替換的節(jié)點咧欣,可以是新的節(jié)點浅缸,也可以是頁面上的節(jié)點,如果是頁面上的節(jié)點魄咕,則其將被轉(zhuǎn)移到新的位置 -
oldChild
是被替換的節(jié)點
4.5 頁面修改型API總結(jié)
- 頁面修改型api主要是這四個接口衩椒,要注意幾個特點:
- 不管是新增還是替換節(jié)點,如果新增或替換的節(jié)點是原本存在頁面上的,則其原來位置的節(jié)點將被移除毛萌,也就是說同一個節(jié)點不能存在于頁面的多個位置
- 節(jié)點本身綁定的事件會不會消失苟弛,會一直保留著
五、節(jié)點查詢型API
- 節(jié)點查詢型
API
也是非常常用的
5.1 document.getElementById
這個接口很簡單阁将,根據(jù)元素
id
返回元素膏秫,返回值是Element
類型,如果不存在該元素冀痕,則返回null
-
使用這個接口有幾點要注意:
- 元素的
Id
是大小寫敏感的荔睹,一定要寫對元素的id
-
HTML
文檔中可能存在多個id
相同的元素,則返回第一個元素 - 只從文檔中進行搜索元素言蛇,如果創(chuàng)建了一個元素并指定
id
僻他,但并沒有添加到文檔中,則這個元素是不會被查找到的
- 元素的
5.2 document.getElementsByTagName
- 這個接口根據(jù)元素標簽名獲取元素腊尚,返回一個即時的
HTMLCollection
類型吨拗,什么是即時的HTMLCollection
類型呢?
<div>div1</div>
<div>div2</div>
<input type="button" value="顯示數(shù)量" id="btnShowCount"/>
<input type="button" value="新增div" id="btnAddDiv"/>
var divList = document.getElementsByTagName("div");
document.getElementById("btnAddDiv").onclick = function(){
var div = document.createElement("div");
div.textContent ="div" + (divList.length+1);
document.body.appendChild(div);
}
document.getElementById("btnShowCount").onclick = function(){
alert(divList.length);
}
這段代碼中有兩個按鈕婿斥,一個按鈕是顯示
HTMLCollection
元素的個數(shù)劝篷,另一個按鈕可以新增一個div標簽到文檔中。前面提到HTMLCollcetion
元素是即時的表示該集合是隨時變化的民宿,也就是是文檔中有幾個div
娇妓,它會隨時進行變化,當我們新增一個div
后活鹰,再訪問HTMLCollection
時哈恰,就會包含這個新增的div
-
使用document.getElementsByTagName這個方法有幾點要注意:
- 如果要對
HTMLCollection
集合進行循環(huán)操作,最好將其長度緩存起來志群,因為每次循環(huán)都會去計算長度着绷,暫時緩存起來可以提高效率 - 如果沒有存在指定的標簽,該接口返回的不
是null
锌云,而是一個空的HTMLCollection
-
“*”
表示所有標簽
- 如果要對
5.3 document.getElementsByName
getElementsByName
主要是通過指定的name
屬性來獲取元素荠医,它返回一個即時的NodeList
對象。一般用于獲取表單元素的·name·屬性-
使用這個接口主要要注意幾點:
- 返回對象是一個即時的
NodeList
桑涎,它是隨時變化的 - 在
HTML
元素中彬向,并不是所有元素都有name
屬性,比如div
是沒有name
屬性的攻冷,但是如果強制設(shè)置div的
name`屬性娃胆,它也是可以被查找到的 - 在
IE
中,如果id
設(shè)置成某個值讲衫,然后傳入getElementsByName
的參數(shù)值和id
值一樣缕棵,則這個元素是會被找到的,所以最好不好設(shè)置同樣的值給id
和name
- 返回對象是一個即時的
5.4 document.getElementsByClassName
- 這個
API
是根據(jù)元素的class
返回一個即時的HTMLCollection
涉兽,用法如下
var elements = document.getElementsByClassName(names);
-
這個接口有下面幾點要注意:
- 返回結(jié)果是一個即時的
HTMLCollection
招驴,會隨時根據(jù)文檔結(jié)構(gòu)變化 -
IE9
以下瀏覽器不支持 - 如果要獲取
2
個以上classname
,可傳入多個classname
枷畏,每個用空格相隔别厘,例如
- 返回結(jié)果是一個即時的
var elements = document.getElementsByClassName("test1 test2");
5.5 document.querySelector和document.querySelectorAll
這兩個
api
很相似,通過css
選擇器來查找元素拥诡,注意選擇器要符合CSS
選擇器的規(guī)則首先來介紹一下
document.querySelector
document.querySelector
返回第一個匹配的元素触趴,如果沒有匹配的元素,則返回null
渴肉。注意冗懦,由于返回的是第一個匹配的元素,這個
api
使用的深度優(yōu)先搜索來獲取元素
<div>
<div>
<span class="test">第三級的span</span>
</div>
</div>
<div class="test">
同級的第二個div
</div>
<input type="button" id="btnGet" value="獲取test元素" />
document.getElementById("btnGet").addEventListener("click",function(){
var element = document.querySelector(".test");
alert(element.textContent);
})
這個例子很簡單仇祭,就是兩個
class
都包含“test”
的元素披蕉,一個在文檔樹的前面,但是它在第三級乌奇,另一個在文檔樹的后面没讲,但它在第一級,通過querySelector
獲取元素時礁苗,它通過深度優(yōu)先搜索爬凑,拿到文檔樹前面的第三級的元素document.querySelectorAll
的不同之處在于它返回的是所有匹配的元素,而且可以匹配多個選擇符
<div class="test">
class為test
</div>
<div id="test">
id為test
</div>
<input id="btnShow" type="button" value="顯示內(nèi)容" />
document.getElementById("btnShow").addEventListener("click",function(){
var elements = document.querySelectorAll("#test,.test");
for(var i = 0,length = elements.length;i<length;i++){
alert(elements[i].textContent);
}
})
-
這段代碼通過
querySelectorAll
试伙,使用id
選擇器和class
選擇器選擇了兩個元素嘁信,并依次輸出其內(nèi)容。要注意兩點:-
querySelectorAll
也是通過深度優(yōu)先搜索迁霎,搜索的元素順序和選擇器的順序無關(guān) - 返回的是一個非即時的
NodeList
吱抚,也就是說結(jié)果不會隨著文檔樹的變化而變化
-
兼容性問題:
querySelector
和querySelectorAll
在ie8
以下的瀏覽器不支持-
小結(jié):
-
document.getElementById
返回一個對象 -
document.getElementsByName
和document.getElementsByClasName
返回一個對象數(shù)組
-
六、節(jié)點關(guān)系型API
[圖片上傳失敗...(image-1d163c-1545535313683)]
- 在
html
文檔中的每個節(jié)點之間的關(guān)系都可以看成是家譜關(guān)系考廉,包含父子關(guān)系秘豹,兄弟關(guān)系等等
6.1 父關(guān)系型API
-
parentNode
:每個節(jié)點都有一個parentNode
屬性,它表示元素的父節(jié)點昌粤。Element
的父節(jié)點可能是Element
既绕,Document
或DocumentFragment
-
parentElement
:返回元素的父元素節(jié)點,與parentNode
的區(qū)別在于涮坐,其父節(jié)點必須是一個Element
凄贩,如果不是,則返回null
6.2 兄弟關(guān)系型API
previousSibling
:節(jié)點的前一個節(jié)點袱讹,如果該節(jié)點是第一個節(jié)點疲扎,則為null
昵时。注意有可能拿到的節(jié)點是文本節(jié)點或注釋節(jié)點,與預(yù)期的不符椒丧,要進行處理一下previousElementSibling
:返回前一個元素節(jié)點壹甥,前一個節(jié)點必須是Element
,注意IE9
以下瀏覽器不支持nextSibling
previousSibling
存在兼容性問題nextElementSibling
previousElementSibling
推薦使用
<script>
var oUl = document.getElementById('ul1');
var firstEle = oUl.firstElementChild;
var lastEle = oUl.lastElementChild;
firstEle.nextElementSibling.style.background = 'red';
lastEle.previousElementSibling.style.background = 'green';
</script>
[圖片上傳失敗...(image-2a3be4-1545535313683)]
-
nextSibling
:節(jié)點的后一個節(jié)點壶熏,如果該節(jié)點是最后一個節(jié)點句柠,則為null
。注意有可能拿到的節(jié)點是文本節(jié)點棒假,與預(yù)期的不符溯职,要進行處理一下 -
nextElementSibling
:返回后一個元素節(jié)點,后一個節(jié)點必須是Element
帽哑,注意IE9
以下瀏覽器不支持
6.3 子關(guān)系型API
-
childNodes
:- 返回一個即時的
NodeList
谜酒,表示元素的子節(jié)點列表,子節(jié)點可能會包含文本節(jié)點妻枕,注釋節(jié)點等甚带。childNodes
子節(jié)點列表集合(只讀屬性 有兼容性問題 )
- 返回一個即時的
<ul id="ul1">
<li>11111</li>
<li>22222</li>
<li>3333</li>
<li>44444</li>
</ul>
<script>
var oUl = document.getElementById('ul1');
console.log(oUl.childNodes);
</script>
[圖片上傳失敗...(image-560f38-1545535313683)]
從截圖中可以看出 這段代碼中
ul
的子節(jié)點有9
個,這說明使用childNodes
獲取的節(jié)點包括了文本節(jié)點和元素節(jié)點childNodes
在低版本的ie
瀏覽器下獲取的節(jié)點只包括元素節(jié)點佳头,這就導(dǎo)致了兼容性問題-
如何解決兼容性鹰贵??
- 根據(jù)子節(jié)點的
nodeType
屬性值判斷
- 根據(jù)子節(jié)點的
for (var i=0; i<oUl.childNodes.length; i++) {
if ( oUl.childNodes[i].nodeType == 1 ) {
oUl.childNodes[i].style.background = 'red';
}
}
-
children
:- 一個即時的
HTMLCollection
康嘉,子節(jié)點都是Element
碉输,IE9
以下瀏覽器不支持。children
子節(jié)點列表集合(只讀屬性 推薦使用 )
- 一個即時的
children
獲取的子節(jié)點只包含元素節(jié)點
for (var i = 0; i<oUl.children.length; i++){
oUl.children[i].style.background = 'red';
}
firstNode
:第一個子節(jié)點lastNode
:最后一個子節(jié)點firstChild
(firstElementChild)lastChild
(lastElementChild) 第一個子節(jié)點 最后一個子節(jié)點firstChild
亭珍、lastChild
和childNodes
同樣的存在兼容性問題敷钾,在低版本ie
瀏覽器中只能獲取到元素節(jié)點firstElementChild
、lastElementChild
獲取第一個元素子節(jié)點肄梨,最后一個元素子節(jié)點 推薦使用
var oUl = document.getElementById('ul1');
// oUl.firstChild.style.background = 'red';//標準瀏覽器 報錯
// oUl.lastChild.style.background = 'red';//標準瀏覽器 報錯
oUl.firstElementChild.style.background = 'red';
oUl.lastElementChild.style.background = 'red';
[圖片上傳失敗...(image-724b20-1545535313683)]
-
hasChildNodes
方法:可以用來判斷是否包含子節(jié)點
七阻荒、元素屬性型
7.1 setAttribute
-
setAttribute
:它允許我們對元素屬性值做出修改與getAttribute
一樣setAttribute
也能用于元素節(jié)點 - 通過
setAttribute
對文檔做出修改后,在通過瀏覽器的查看源碼選項看到的任然是改變之前的屬性值众羡,也就是說setAttribue
做出的修改侨赡,不會反應(yīng)到文檔本身的源碼里 -
setAttribute
優(yōu)勢在于可以修改文檔中的任何一個屬性
element.setAttribute(name, value);
- 其中
name
是特性名,value
是特性值粱侣。如果元素不包含該特性羊壹,則會創(chuàng)建該特性并賦值。 - 如果元素本身包含指定的特性名為屬性齐婴,則可以訪問屬性進行賦值油猫,比如下面兩條代碼是等價
element.setAttribute("id","test");
element.id = "test";
-
非DOM的解決方案
- 其實不用
setAttribute
也可以改變元素的屬性 -
setAttribute
方法是第一級DOM
的組成部分,它可以設(shè)計任何元素節(jié)點的任意屬性柠偶。在第1級DOM
出現(xiàn)之前情妖,你可以通過另外一種辦法設(shè)置大部分元素的屬性
- 其實不用
element.value = "the new value";
與下面語句等價
element.setAttribute("value","the new value");
7.2 getAttribute
-
getAttribute
返回指定的特性名相應(yīng)的特性值睬关,如果不存在,則返回null
或空字符串毡证。 -
getAttribute
不屬性doucment
對象共螺,不能通過document
對象調(diào)用,只能通過元素節(jié)點對象調(diào)用 - 例如可以與
getElementsByTagName
方法合用情竹,獲取每個p
的title
屬性
var paras = document.getElementsByTagName("p");
for(var i=0;i<para.lenght;i++){
alert(paras.getAttrtitube("title"));
}
八、表格操作
九匀哄、樣式操作
十秦效、大小和偏移
十一、網(wǎng)上的一張思維導(dǎo)圖總結(jié)
- 參考
-
JavaScript DOM
編程藝術(shù) - 常用DOM操作
-