W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗值獎勵
DOM是文檔對象模型(Document Object Model)的簡稱,它的基本思想是把結(jié)構(gòu)化文檔(比如HTML和XML)解析成一系列的節(jié)點,再由這些節(jié)點組成一個樹狀結(jié)構(gòu)(DOM Tree)。所有的節(jié)點和最終的樹狀結(jié)構(gòu),都有規(guī)范的對外接口,以達到使用編程語言操作文檔的目的(比如增刪內(nèi)容)。所以,DOM可以理解成文檔(HTML文檔、XML文檔和SVG文檔)的編程接口。
DOM有自己的國際標準,目前的通用版本是DOM 3,下一代版本DOM 4正在擬定中。本章介紹的就是JavaScript對DOM標準的實現(xiàn)和用法。
嚴格地說,DOM不屬于JavaScript,但是操作DOM是JavaScript最常見的任務(wù),而JavaScript也是最常用于DOM操作的語言。所以,DOM往往放在JavaScript里面介紹。
DOM的最小組成單位叫做節(jié)點(node),一個文檔的樹形結(jié)構(gòu)(DOM樹),就是由各種不同類型的節(jié)點組成。
對于HTML文檔,節(jié)點主要有以下六種類型:Document節(jié)點、DocumentType節(jié)點、Element節(jié)點、Attribute節(jié)點、Text節(jié)點和DocumentFragment節(jié)點。
節(jié)點 | 名稱 | 含義 |
---|---|---|
Document | 文檔節(jié)點 | 整個文檔(window.document) |
DocumentType | 文檔類型節(jié)點 | 文檔的類型(比如) |
Element | 元素節(jié)點 | HTML元素(比如、等) |
Attribute | 屬性節(jié)點 | HTML元素的屬性(比如class="right") |
Text | 文本節(jié)點 | HTML文檔中出現(xiàn)的文本 |
DocumentFragment | 文檔碎片節(jié)點 | 文檔的片段 |
瀏覽器原生提供一個Node對象,上表所有類型的節(jié)點都是Node對象派生出來的。也就是說,它們都繼承了Node的屬性和方法。
nodeName屬性返回節(jié)點的名稱,nodeType屬性返回節(jié)點的常數(shù)值。具體的返回值,可查閱下方的表格。
類型 | nodeName | nodeType |
---|---|---|
DOCUMENT_NODE | #document | 9 |
ELEMENT_NODE | 大寫的HTML元素名 | 1 |
ATTRIBUTE_NODE | 等同于Attr.name | 2 |
TEXT_NODE | #text | 3 |
DOCUMENT_FRAGMENT_NODE | #document-fragment | 11 |
DOCUMENT_TYPE_NODE | 等同于DocumentType.name | 10 |
以document節(jié)點為例,它的nodeName屬性等于#document,nodeType屬性等于9。
document.nodeName // "#document"
document.nodeType // 9
通常來說,使用nodeType屬性確定一個節(jié)點的類型,比較方便。
document.querySelector('a').nodeType === 1
// true
document.querySelector('a').nodeType === Node.ELEMENT_NODE
// true
上面兩種寫法是等價的。
以下屬性返回當前節(jié)點的相關(guān)節(jié)點。
(1)ownerDocument
ownerDocument屬性返回當前節(jié)點所在的頂層文檔對象,即document對象。
var d = p.ownerDocument;
d === document // true
document對象本身的ownerDocument屬性,返回null。
(2)nextSibling
nextsibling屬性返回緊跟在當前節(jié)點后面的第一個同級節(jié)點。如果當前節(jié)點后面沒有同級節(jié)點,則返回null。注意,該屬性還包括文本節(jié)點和評論節(jié)點。因此如果當前節(jié)點后面有空格,該屬性會返回一個文本節(jié)點,內(nèi)容為空格。
var el = document.getelementbyid('div-01').firstchild;
var i = 1;
while (el) {
console.log(i + '. ' + el.nodename);
el = el.nextsibling;
i++;
}
上面代碼遍歷div-01節(jié)點的所有子節(jié)點。
(3)previousSibling
previoussibling屬性返回當前節(jié)點前面的、距離最近的一個同級節(jié)點。如果當前節(jié)點前面沒有同級節(jié)點,則返回null。
// html代碼如下
// <a><b1 id="b1"/><b2 id="b2"/></a>
document.getelementbyid("b1").previoussibling // null
document.getelementbyid("b2").previoussibling.id // "b1"
對于當前節(jié)點前面有空格,則previoussibling屬性會返回一個內(nèi)容為空格的文本節(jié)點。
(4)parentNode
parentNode屬性返回當前節(jié)點的父節(jié)點。對于一個節(jié)點來說,它的父節(jié)點只可能是三種類型:element節(jié)點、document節(jié)點和documentfragment節(jié)點。
下面代碼是如何從父節(jié)點移除指定節(jié)點。
if (node.parentNode) {
node.parentNode.removeChild(node);
}
對于document節(jié)點和documentfragment節(jié)點,它們的父節(jié)點都是null。另外,對于那些生成后還沒插入DOM樹的節(jié)點,父節(jié)點也是null。
(5)parentElement
parentElement屬性返回當前節(jié)點的父Element節(jié)點。如果當前節(jié)點沒有父節(jié)點,或者父節(jié)點類型不是Element節(jié)點,則返回null。
if (node.parentElement) {
node.parentElement.style.color = "red";
}
上面代碼設(shè)置指定節(jié)點的父Element節(jié)點的CSS屬性。
在IE瀏覽器中,只有Element節(jié)點才有該屬性,其他瀏覽器則是所有類型的節(jié)點都有該屬性。
以下屬性返回當前節(jié)點的內(nèi)容。
(1)textContent
textContent屬性返回當前節(jié)點和它的所有后代節(jié)點的文本內(nèi)容。
// HTML代碼為
// <div id="divA">This is <span>some</span> text</div>
document.getElementById("divA").textContent
// This is some text
上面代碼的textContent屬性,自動忽略當前節(jié)點內(nèi)部的HTML標簽,返回所有文本內(nèi)容。
該屬性是可讀寫的,設(shè)置該屬性的值,會用一個新的文本節(jié)點,替換所有它原來的子節(jié)點。它還有一個好處,就是自動對HTML標簽轉(zhuǎn)義。這很適合用于用戶提供的內(nèi)容。
document.getElementById('foo').textContent = '<p>GoodBye!</p>';
上面代碼在插入文本時,會將p標簽解釋為文本,即<p>,而不會當作標簽處理。
對于Text節(jié)點和Comment節(jié)點,該屬性的值與nodeValue屬性相同。對于其他類型的節(jié)點,該屬性會將每個子節(jié)點的內(nèi)容連接在一起返回,但是不包括Comment節(jié)點。如果一個節(jié)點沒有子節(jié)點,則返回空字符串。
document節(jié)點和doctype節(jié)點的textContent屬性為null。如果要讀取整個文檔的內(nèi)容,可以使用document.documentElement.textContent
。
在IE瀏覽器,所有Element節(jié)點都有一個innerText屬性。它與textContent屬性基本相同,但是有幾點區(qū)別。
innerText受CSS影響,textcontent不受。比如,如果CSS規(guī)則隱藏(hidden)了某段文本,innerText就不會返回這段文本,textcontent則照樣返回。
innerText返回的文本,會過濾掉空格、換行和回車鍵,textcontent則不會。
(2)nodeValue
nodeValue屬性返回或設(shè)置當前節(jié)點的值,格式為字符串。但是,該屬性只對Text節(jié)點、Comment節(jié)點、XML文檔的CDATA節(jié)點有效,其他類型的節(jié)點一律返回null。
因此,nodeValue屬性一般只用于Text節(jié)點。對于那些返回null的節(jié)點,設(shè)置nodeValue屬性是無效的。
以下屬性返回當前節(jié)點的子節(jié)點。
(1)childNodes
childNodes屬性返回一個NodeList集合,成員包括當前節(jié)點的所有子節(jié)點。注意,除了HTML元素節(jié)點,該屬性返回的還包括Text節(jié)點和Comment節(jié)點。如果當前節(jié)點不包括任何子節(jié)點,則返回一個空的NodeList集合。由于NodeList對象是一個動態(tài)集合,一旦子節(jié)點發(fā)生變化,立刻會反映在返回結(jié)果之中。
var ulElementChildNodes = document.querySelector('ul').childNodes;
(2)firstNode
firstNode屬性返回當前節(jié)點的第一個子節(jié)點,如果當前節(jié)點沒有子節(jié)點,則返回null。注意,除了HTML元素子節(jié)點,該屬性還包括文本節(jié)點和評論節(jié)點。
(3)lastChild
lastChild屬性返回當前節(jié)點的最后一個子節(jié)點,如果當前節(jié)點沒有子節(jié)點,則返回null。
baseURI屬性返回一個字符串,由當前網(wǎng)頁的協(xié)議、域名和所在的目錄組成,表示當前網(wǎng)頁的絕對路徑。如果無法取到這個值,則返回null。瀏覽器根據(jù)這個屬性,計算網(wǎng)頁上的相對路徑的URL。該屬性為只讀。
通常情況下,該屬性由當前網(wǎng)址的URL(即window.location屬性)決定,但是可以使用HTML的標簽,改變該屬性的值。
<base rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" >
<base target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" >
該屬性不僅document對象有(document.baseURI
),元素節(jié)點也有(element.baseURI
)。通常情況下,它們的值是相同的。
以下方法與子節(jié)點相關(guān)。
(1)appendChild()
appendChild方法接受一個節(jié)點對象作為參數(shù),將其作為最后一個子節(jié)點,插入當前節(jié)點。
var p = document.createElement("p");
document.body.appendChild(p);
如果參數(shù)節(jié)點是文檔中現(xiàn)有的其他節(jié)點,appendChild方法會將其從原來的位置,移動到新位置。
hasChildNodes方法返回一個布爾值,表示當前節(jié)點是否有子節(jié)點。
var foo = document.getElementById("foo");
if ( foo.hasChildNodes() ) {
foo.removeChild( foo.childNodes[0] );
}
上面代碼表示,如果foo節(jié)點有子節(jié)點,就移除第一個子節(jié)點。
(2)hasChildNodes()
hasChildNodes方法結(jié)合firstChild屬性和nextSibling屬性,可以遍歷當前節(jié)點的所有后代節(jié)點。
function DOMComb (oParent, oCallback) {
if (oParent.hasChildNodes()) {
for (var oNode = oParent.firstChild; oNode; oNode = oNode.nextSibling) {
DOMComb(oNode, oCallback);
}
}
oCallback.call(oParent);
}
上面代碼的DOMComb函數(shù)的第一個參數(shù)是某個指定的節(jié)點,第二個參數(shù)是回調(diào)函數(shù)。這個回調(diào)函數(shù)會依次作用于指定節(jié)點,以及指定節(jié)點的所有后代節(jié)點。
function printContent () {
if (this.nodeValue) {
console.log(this.nodeValue);
}
}
DOMComb(document.body, printContent);
下面方法與節(jié)點操作有關(guān)。
(1)cloneNode()
cloneNode方法用于克隆一個節(jié)點。它接受一個布爾值作為參數(shù),表示是否同時克隆子節(jié)點,默認是false,即不克隆子節(jié)點。
var cloneUL = document.querySelector('ul').cloneNode(true);
需要注意的是,克隆一個節(jié)點,會拷貝該節(jié)點的所有屬性,但是會喪失addEventListener方法和on-屬性(即node.onclick = fn
),添加在這個節(jié)點上的事件回調(diào)函數(shù)。
克隆一個節(jié)點之后,DOM樹有可能出現(xiàn)兩個有相同ID屬性(即id="xxx"
)的HTML元素,這時應(yīng)該修改其中一個HTML元素的ID屬性。
(2)insertBefore()
insertBefore方法用于將某個節(jié)點插入當前節(jié)點的指定位置。它接受兩個參數(shù),第一個參數(shù)是所要插入的節(jié)點,第二個參數(shù)是當前節(jié)點的一個子節(jié)點,新的節(jié)點將插在這個節(jié)點的前面。該方法返回被插入的新節(jié)點。
var text1 = document.createTextNode('1');
var li = document.createElement('li');
li.appendChild(text1);
var ul = document.querySelector('ul');
ul.insertBefore(li,ul.firstChild);
上面代碼在ul節(jié)點的最前面,插入一個新建的li節(jié)點。
如果insertBefore方法的第二個參數(shù)為null,則新節(jié)點將插在當前節(jié)點的最后位置,即變成最后一個子節(jié)點。
將新節(jié)點插在當前節(jié)點的最前面(即變成第一個子節(jié)點),可以使用當前節(jié)點的firstChild屬性。
parentElement.insertBefore(newElement, parentElement.firstChild);
上面代碼中,如果當前節(jié)點沒有任何子節(jié)點,parentElement.firstChild
會返回null,則新節(jié)點會插在當前節(jié)點的最后,等于是第一個子節(jié)點。
由于不存在insertAfter方法,如果要插在當前節(jié)點的某個子節(jié)點后面,可以用insertBefore方法結(jié)合nextSibling屬性模擬。
parentDiv.insertBefore(s1, s2.nextSibling);
上面代碼可以將s1節(jié)點,插在s2節(jié)點的后面。如果s2是當前節(jié)點的最后一個子節(jié)點,則s2.nextSibling
返回null,這時s1節(jié)點會插在當前節(jié)點的最后,變成當前節(jié)點的最后一個子節(jié)點,等于緊跟在s2的后面。
(3)removeChild()
removeChild方法接受一個子節(jié)點作為參數(shù),用于從當前節(jié)點移除該節(jié)點。它返回被移除的節(jié)點。
var divA = document.getElementById('A');
divA.parentNode.removeChild(divA);
上面代碼是如何移除一個指定節(jié)點。
下面是如何移除當前節(jié)點的所有子節(jié)點。
var element = document.getElementById("top");
while (element.firstChild) {
element.removeChild(element.firstChild);
}
被移除的節(jié)點依然存在于內(nèi)存之中,但是不再是DOM的一部分。所以,一個節(jié)點移除以后,依然可以使用它,比如插入到另一個節(jié)點。
(4)replaceChild()
replaceChild方法用于將一個新的節(jié)點,替換當前節(jié)點的某一個子節(jié)點。它接受兩個參數(shù),第一個參數(shù)是用來替換的新節(jié)點,第二個參數(shù)將要被替換走的子節(jié)點。它返回被替換走的那個節(jié)點。
replacedNode = parentNode.replaceChild(newChild, oldChild);
下面是一個例子。
var divA = document.getElementById('A');
var newSpan = document.createElement('span');
newSpan.textContent = 'Hello World!';
divA.parentNode.replaceChild(newSpan,divA);
上面代碼是如何替換指定節(jié)點。
下面方法用于節(jié)點的互相比較。
(1)contains()
contains方法接受一個節(jié)點作為參數(shù),返回一個布爾值,表示參數(shù)節(jié)點是否為當前節(jié)點的后代節(jié)點。
document.body.contains(node)
上面代碼檢查某個節(jié)點,是否包含在當前文檔之中。
注意,如果將當前節(jié)點傳入contains方法,會返回true。雖然從意義上說,一個節(jié)點不應(yīng)該包含自身。
nodeA.contains(nodeA) // true
(2)compareDocumentPosition()
compareDocumentPosition方法的用法,與contains方法完全一致,返回一個7個比特位的二進制值,表示參數(shù)節(jié)點與當前節(jié)點的關(guān)系。
二進制值 | 數(shù)值 | 含義 |
---|---|---|
000000 | 0 | 兩個節(jié)點相同 |
000001 | 1 | 兩個節(jié)點不在同一個文檔(即有一個節(jié)點不在當前文檔) |
000010 | 2 | 參數(shù)節(jié)點在當前節(jié)點的前面 |
000100 | 4 | 參數(shù)節(jié)點在當前節(jié)點的后面 |
001000 | 8 | 參數(shù)節(jié)點包含當前節(jié)點 |
010000 | 16 | 當前節(jié)點包含參數(shù)節(jié)點 |
100000 | 32 | 瀏覽器的私有用途 |
// HTML代碼為
// <div id="writeroot">
// <form>
// <input id="test" />
// </form>
// </div>
var x = document.getElementById('writeroot');
var y = document.getElementById('test');
x.compareDocumentPosition(y) // 20
y.compareDocumentPosition(x) // 10
上面代碼中,節(jié)點x包含節(jié)點y,而且節(jié)點y在節(jié)點x的后面,所以第一個compareDocumentPosition方法返回20(010100),第二個compareDocumentPosition方法返回10(0010010)。
由于compareDocumentPosition返回值的含義,定義在每一個比特位上,所以如果要檢查某一種特定的含義,就需要使用比特位運算符。
var head = document.head;
var body = document.body;
if (head.compareDocumentPosition(body) & 4) {
console.log("文檔結(jié)構(gòu)正確");
} else {
console.log("<head> 不能在 <body> 前面");
}
上面代碼中,compareDocumentPosition的返回值與4(又稱掩碼)進行與運算(&),得到一個布爾值,表示head是否在body前面。
在這個方法的基礎(chǔ)上,可以部署一些特定的函數(shù),檢查節(jié)點的位置。
Node.prototype.before = function (arg) {
return !!(this.compareDocumentPosition(arg) & 2)
}
nodeA.before(nodeB)
上面代碼在Node對象上部署了一個before方法,返回一個布爾值,表示參數(shù)節(jié)點是否在當前節(jié)點的前面。
(3)isEqualNode()
isEqualNode方法返回一個布爾值,用于檢查兩個節(jié)點是否相等。所謂相等的節(jié)點,指的是兩個節(jié)點的類型相同、屬性相同、子節(jié)點相同。
var targetEl = document.getElementById("targetEl");
var firstDiv = document.getElementsByTagName("div")[0];
targetEl.isEqualNode(firstDiv)
normailize方法用于清理當前節(jié)點內(nèi)部的所有Text節(jié)點。它會去除空的文本節(jié)點,并且將毗鄰的文本節(jié)點合并成一個。
var wrapper = document.createElement("div");
wrapper.appendChild(document.createTextNode("Part 1 "));
wrapper.appendChild(document.createTextNode("Part 2 "));
wrapper.childNodes.length // 2
wrapper.normalize();
wrapper.childNodes.length // 1
上面代碼使用normalize方法之前,wrapper節(jié)點有兩個Text子節(jié)點。使用normalize方法之后,兩個Text子節(jié)點被合并成一個。
該方法是Text.splitText
的逆方法,可以查看《Text節(jié)點》章節(jié),了解更多內(nèi)容。
節(jié)點對象都是單個節(jié)點,但是有時會需要一種數(shù)據(jù)結(jié)構(gòu),能夠容納多個節(jié)點。DOM提供兩種接口,用于部署這種節(jié)點的集合:NodeList接口和HTMLCollection接口。
有些屬性和方法返回的是一組節(jié)點,比如Node.childNodes、document.querySelectorAll()。它們返回的都是一個部署了NodeList接口的對象。
NodeList接口有時返回一個動態(tài)集合,有時返回一個靜態(tài)集合。所謂動態(tài)集合就是一個活的集合,DOM樹刪除或新增一個相關(guān)節(jié)點,都會立刻反映在NodeList接口之中。Node.childNodes返回的,就是一個動態(tài)集合。
var parent = document.getElementById('parent');
parent.childNodes.length // 2
parent.appendChild(document.createElement('div'));
parent.childNodes.length // 3
上面代碼中,parent.childNodes
返回的是一個部署了NodeList接口的對象。當parent節(jié)點新增一個子節(jié)點以后,該對象的成員個數(shù)就增加了1。
document.querySelectorAll方法返回的是一個靜態(tài),DOM內(nèi)部的變化,并不會實時反映在該方法的返回結(jié)果之中。
NodeList接口提供length屬性和數(shù)字索引,因此可以像數(shù)組那樣,使用數(shù)字索引取出每個節(jié)點,但是它本身并不是數(shù)組,不能使用pop或push之類數(shù)組特有的方法。
// 數(shù)組的繼承鏈
myArray --> Array.prototype --> Object.prototype --> null
// NodeList的繼承鏈
myNodeList --> NodeList.prototype --> Object.prototype --> null
從上面的繼承鏈可以看到,NodeList接口對象并不繼承Array.prototype,因此不具有數(shù)組接口提供的方法。如果要在NodeList接口使用數(shù)組方法,可以將NodeList接口對象轉(zhuǎn)為真正的數(shù)組。
var div_list = document.querySelectorAll('div');
var div_array = Array.prototype.slice.call(div_list);
也可以通過下面的方法調(diào)用。
var forEach = Array.prototype.forEach;
forEach.call(element.childNodes, function(child){
child.parentNode.style.color = '#0F0';
});
上面代碼讓數(shù)組的forEach方法在NodeList接口對象上調(diào)用。
不過,遍歷NodeList接口對象的首選方法,還是使用for循環(huán)。
for (var i = 0; i < myNodeList.length; ++i) {
var item = myNodeList[i];
}
不要使用for...in循環(huán)去遍歷NodeList接口對象,因為for...in循環(huán)會將非數(shù)字索引的length屬性和下面要講到的item方法,也遍歷進去,而且不保證各個成員遍歷的順序。
ES6新增的for...of循環(huán),也可以正確遍歷NodeList接口對象。
var list = document.querySelectorAll( 'input[type=checkbox]' );
for (var item of list) {
item.checked = true;
}
NodeList接口提供item方法,接受一個數(shù)字索引作為參數(shù),返回該索引對應(yīng)的成員。如果取不到成員,或者索引不合法,則返回null。
nodeItem = nodeList.item(index)
// 實例
var divs = document.getElementsByTagName("div");
var secondDiv = divs.item(1);
上面代碼中,由于數(shù)字索引從零開始計數(shù),所以取出第二個成員,要使用數(shù)字索引1。
所有類似數(shù)組的對象,都可以使用方括號運算符取出成員,所以一般情況下,都是使用下面的寫法,而不使用item方法。
nodeItem = nodeList[index]
HTMLCollection接口與NodeList接口類似,也是節(jié)點的集合,但是集合成員都是Element節(jié)點。該接口都是動態(tài)集合,節(jié)點的變化會實時反映在集合中。document.links、docuement.forms、document.images等屬性,返回的都是HTMLCollection接口對象。
部署了該接口的對象,具有l(wèi)ength屬性和數(shù)字索引,因此是一個類似于數(shù)組的對象。
item方法根據(jù)成員的位置參數(shù)(從0開始),返回該成員。如果取不到成員或數(shù)字索引不合法,則返回null。
var c = document.images;
var img1 = c.item(10);
// 等價于下面的寫法
var img1 = c[1];
namedItem方法根據(jù)成員的ID屬性或name屬性,返回該成員。如果沒有對應(yīng)的成員,則返回null。
// HTML代碼為
// <form id="myForm"></form>
var elem = document.forms.namedItem("myForm");
// 等價于下面的寫法
var elem = document.forms["myForm"];
由于item方法和namedItem方法,都可以用方括號運算符代替,所以建議一律使用方括號運算符。
不同的節(jié)點除了繼承Node接口以外,還會繼承其他接口。ParentNode接口用于獲取當前節(jié)點的Element子節(jié)點,ChildNode接口用于處理當前節(jié)點的子節(jié)點(包含但不限于Element子節(jié)點)。
ParentNode接口用于獲取Element子節(jié)點。Element節(jié)點、Document節(jié)點和DocumentFragment節(jié)點,部署了ParentNode接口。凡是這三類節(jié)點,都具有以下四個屬性,用于獲取Element子節(jié)點。
(1)children
children屬性返回一個動態(tài)的HTMLCollection集合,由當前節(jié)點的所有Element子節(jié)點組成。
下面代碼遍歷指定節(jié)點的所有Element子節(jié)點。
if (el.children.length) {
for (var i = 0; i < el.children.length; i++) {
// ...
}
}
(2)firstElementChild
firstChild屬性返回當前節(jié)點的第一個Element子節(jié)點,如果不存在任何Element子節(jié)點,則返回null。
document.firstElementChild.nodeName
// "HTML"
上面代碼中,document節(jié)點的第一個Element子節(jié)點是。
(3)lastElementChild
lastElementChild屬性返回當前節(jié)點的最后一個Element子節(jié)點,如果不存在任何Element子節(jié)點,則返回null。
document.lastElementChild.nodeName
// "HTML"
上面代碼中,document節(jié)點的最后一個Element子節(jié)點是。
(4)childElementCount
childElementCount屬性返回當前節(jié)點的所有Element子節(jié)點的數(shù)目。
ChildNode接口用于處理子節(jié)點(包含但不限于Element子節(jié)點)。Element節(jié)點、DocumentType節(jié)點和CharacterData接口,部署了ChildNode接口。凡是這三類節(jié)點(接口),都可以使用下面四個方法。但是現(xiàn)實的情況是,除了第一個remove方法,目前沒有瀏覽器支持后面三個方法。
(1)remove()
remove方法用于移除當前節(jié)點。
el.remove()
上面方法在DOM中移除了el節(jié)點。注意,調(diào)用這個方法的節(jié)點,是被移除的節(jié)點本身,而不是它的父節(jié)點。
(2)before()
before方法用于在當前節(jié)點的前面,插入一個同級節(jié)點。如果參數(shù)是節(jié)點對象,插入DOM的就是該節(jié)點對象;如果參數(shù)是文本,插入DOM的就是參數(shù)對應(yīng)的文本節(jié)點。
(3)after()
after方法用于在當前節(jié)點的后面,插入一個同級節(jié)點。如果參數(shù)是節(jié)點對象,插入DOM的就是該節(jié)點對象;如果參數(shù)是文本,插入DOM的就是參數(shù)對應(yīng)的文本節(jié)點。
(4)replaceWith()
replaceWith方法使用參數(shù)指定的節(jié)點,替換當前節(jié)點。如果參數(shù)是節(jié)點對象,替換當前節(jié)點的就是該節(jié)點對象;如果參數(shù)是文本,替換當前節(jié)點的就是參數(shù)對應(yīng)的文本節(jié)點。
html元素是網(wǎng)頁的根元素,document.documentElement就指向這個元素。
(1)clientWidth屬性,clientHeight屬性
這兩個屬性返回視口(viewport)的大小,單位為像素。所謂“視口”,是指用戶當前能夠看見的那部分網(wǎng)頁的大小
document.documentElement.clientWidth和document.documentElement.clientHeight,基本上與window.innerWidth和window.innerHeight同義。只有一個區(qū)別,前者不將滾動條計算在內(nèi)(很顯然,滾動條和工具欄會減小視口大?。笳甙藵L動條的高度和寬度。
(2)offsetWidth屬性,offsetHeight屬性
這兩個屬性返回html元素的寬度和高度,即網(wǎng)頁的總寬度和總高度。
dataset屬性用于操作HTML標簽元素的data-*屬性。目前,F(xiàn)irefox、Chrome、Opera、Safari瀏覽器支持該API。
假設(shè)有如下的網(wǎng)頁代碼。
<div id="myDiv" data-id="myId"></div>
以data-id屬性為例,要讀取這個值,可以用dataset.id。
var id = document.getElementById("myDiv").dataset.id;
要設(shè)置data-id屬性,可以直接對dataset.id賦值。這時,如果data-id屬性不存在,將會被創(chuàng)造出來。
document.getElementById("myDiv").dataset.id = "hello";
刪除一個data-*屬性,可以直接使用delete命令。
delete document.getElementById("myDiv").dataset.id
IE 9不支持dataset屬性,可以用 getAttribute('data-foo')、removeAttribute('data-foo')、setAttribute('data-foo')、hasAttribute('data-foo') 代替。
需要注意的是,dataset屬性使用駱駝拼寫法表示屬性名,這意味著data-hello-world會用dataset.helloWorld表示。而如果此時存在一個data-helloWorld屬性,該屬性將無法讀取,也就是說,data屬性本身只能使用連詞號,不能使用駱駝拼寫法。
tabindex屬性用來指定,當前HTML元素節(jié)點是否被tab鍵遍歷,以及遍歷的優(yōu)先級。
var b1 = document.getElementById("button1");
b1.tabIndex = 1;
如果 tabindex = -1 ,tab鍵跳過當前元素。
如果 tabindex = 0 ,表示tab鍵將遍歷當前元素。如果一個元素沒有設(shè)置tabindex,默認值就是0。
如果 tabindex 大于0,表示tab鍵優(yōu)先遍歷。值越大,就表示優(yōu)先級越大。
(1)offsetParent屬性、offsetTop屬性和offsetLeft屬性
這三個屬性提供Element對象在頁面上的位置。
如果Element對象的父對象都沒有將position屬性設(shè)置為非static的值(比如absolute或relative),則offsetParent屬性指向body元素。另外,計算offsetTop和offsetLeft的時候,是從邊框的左上角開始計算,即Element對象的border寬度不計入offsetTop和offsetLeft。
style屬性用來讀寫頁面元素的行內(nèi)CSS屬性,詳見本章《CSS操作》一節(jié)。
(1)選擇子元素的方法
Element對象也部署了document對象的4個選擇子元素的方法,而且用法完全一樣。
上面四個方法只用于選擇Element對象的子節(jié)點。因此,可以采用鏈式寫法來選擇子節(jié)點。
document.getElementById('header').getElementsByClassName('a')
各大瀏覽器對這四個方法都支持良好,IE的情況如下:IE 6開始支持getElementsByTagName,IE 8開始支持querySelector和querySelectorAll,IE 9開始支持getElementsByClassName。
(2)elementFromPoint方法
該方法用于選擇在指定坐標的最上層的Element對象。
document.elementFromPoint(50,50)
上面代碼了選中在(50,50)這個坐標的最上層的那個HTML元素。
(3)HTML元素的屬性相關(guān)方法
(4)matchesSelector方法
該方法返回一個布爾值,表示Element對象是否符合某個CSS選擇器。
document.querySelector('li').matchesSelector('li:first-child')
這個方法需要加上瀏覽器前綴,需要寫成mozMatchesSelector()、webkitMatchesSelector()、oMatchesSelector()、msMatchesSelector()。
(5)focus方法
focus方法用于將當前頁面的焦點,轉(zhuǎn)移到指定元素上。
document.getElementById('my-span').focus();
表格有一些特殊的DOM操作方法。
下面是使用JavaScript生成表格的一個例子。
var table = document.createElement('table');
var tbody = document.createElement('tbody');
table.appendChild(tbody);
for (var i = 0; i <= 9; i++) {
var rowcount = i + 1;
tbody.insertRow(i);
tbody.rows[i].insertCell(0);
tbody.rows[i].insertCell(1);
tbody.rows[i].insertCell(2);
tbody.rows[i].cells[0].appendChild(document.createTextNode('Row ' + rowcount + ', Cell 1'));
tbody.rows[i].cells[1].appendChild(document.createTextNode('Row ' + rowcount + ', Cell 2'));
tbody.rows[i].cells[2].appendChild(document.createTextNode('Row ' + rowcount + ', Cell 3'));
}
table.createCaption();
table.caption.appendChild(document.createTextNode('A DOM-Generated Table'));
document.body.appendChild(table);
這些代碼相當易讀,其中需要注意的就是insertRow和insertCell方法,接受一個表示位置的參數(shù)(從0開始的整數(shù))。
table元素有以下屬性:
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: