溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

DOM 基礎(chǔ)

發(fā)布時(shí)間:2020-05-24 16:15:45 來(lái)源:網(wǎng)絡(luò) 閱讀:409 作者:菜鳥(niǎo)不菜么 欄目:web開(kāi)發(fā)

DOM 介紹

DOM 中的三個(gè)字母,D(文檔)可以理解為整個(gè) Web 加載的網(wǎng)頁(yè)文檔;O(對(duì)象)可

以理解為類(lèi)似 window 對(duì)象之類(lèi)的東西,可以調(diào)用屬性和方法,這里我們說(shuō)的是 document

對(duì)象;M(模型)可以理解為網(wǎng)頁(yè)文檔的樹(shù)型結(jié)構(gòu)。

DOM 有三個(gè)等級(jí),分別是 DOM1、DOM2、DOM3,并且 DOM1 在 1998 年 10 月成為

W3C 標(biāo)準(zhǔn)。DOM1 所支持的瀏覽器包括 IE6+、Firefox、Safari、Chrome 和 Opera1.7+。

PS:IE 中的所有 DOM 對(duì)象都是以 COM 對(duì)象的形式實(shí)現(xiàn)的,這意味著 IE 中的 DOM

可能會(huì)和其他瀏覽器有一定的差異。

1.節(jié)點(diǎn)

加載 HTML 頁(yè)面時(shí),Web 瀏覽器生成一個(gè)樹(shù)型結(jié)構(gòu),用來(lái)表示頁(yè)面內(nèi)部結(jié)構(gòu)。DOM 將

這種樹(shù)型結(jié)構(gòu)理解為由節(jié)點(diǎn)組成。

html 標(biāo)簽沒(méi)有父輩,沒(méi)有兄弟,所以 html 標(biāo)

簽為根標(biāo)簽。head 標(biāo)簽是 html 子標(biāo)簽,meta 和 title 標(biāo)簽之間是兄弟關(guān)系。如果把每個(gè)標(biāo)簽

當(dāng)作一個(gè)節(jié)點(diǎn)的話,那么這些節(jié)點(diǎn)組合成了一棵節(jié)點(diǎn)樹(shù)

PS:后面我們經(jīng)常把標(biāo)簽稱作為元素,是一個(gè)意思。

2.節(jié)點(diǎn)種類(lèi):元素節(jié)點(diǎn)、文本節(jié)點(diǎn)、屬性節(jié)點(diǎn)。

<div title="屬性節(jié)點(diǎn)">測(cè)試 Div</div>


查找元素

W3C 提供了比較方便簡(jiǎn)單的定位節(jié)點(diǎn)的方法和屬性,以便我們快速的對(duì)節(jié)點(diǎn)進(jìn)行操作。

分別為:getElementById()、getElementsByTagName()、getElementsByName()、getAttribute()、

setAttribute()和 removeAttribute()

1.getElementById()方法

getElementById()方法,接受一個(gè)參數(shù):獲取元素的 ID。如果找到相應(yīng)的元素則返回該

元素的 HTMLDivElement 對(duì)象,如果不存在,則返回 null。

document.getElementById('box'); //獲取 id 為 box 的元素節(jié)點(diǎn)

PS:上面的例子,默認(rèn)情況返回 null,這無(wú)關(guān)是否存在 id="box"的標(biāo)簽,而是執(zhí)行順序

問(wèn)題。解決方法,1.把 script 調(diào)用標(biāo)簽移到 html 末尾即可;2.使用 onload 事件來(lái)處理 JS,等

待 html 加載完畢再加載 onload 事件里的 JS。

window.onload = function () { //預(yù)加載 html 后執(zhí)行

document.getElementById('box');

};

PS:id 表示一個(gè)元素節(jié)點(diǎn)的唯一性,不能同時(shí)給兩個(gè)或以上的元素節(jié)點(diǎn)創(chuàng)建同一個(gè)命

名的 id。某些低版本的瀏覽器會(huì)無(wú)法識(shí)別 getElementById()方法,比如 IE5.0-,這時(shí)需要做

一些判斷,可以結(jié)合上章的瀏覽器檢測(cè)來(lái)操作。

if (document.getElementById) { //判斷是否支持 getElementById

alert('當(dāng)前瀏覽器支持 getElementById');

}

當(dāng)我們通過(guò) getElementById()獲取到特定元素節(jié)點(diǎn)時(shí),這個(gè)節(jié)點(diǎn)對(duì)象就被我們獲取到了,

而通過(guò)這個(gè)節(jié)點(diǎn)對(duì)象,我們可以訪問(wèn)它的一系列屬性。

document.getElementById('box').tagName; //DIV

document.getElementById('box').innerHTML; //測(cè)試 Div

document.getElementById('box').id; //獲取 id

document.getElementById('box').id = 'person'; //設(shè)置 id

document.getElementById('box').title; //獲取 title

document.getElementById('box').title = '標(biāo)題' //設(shè)置 title

document.getElementById('box').style; //獲取 CSSStyleDeclaration 對(duì)象

document.getElementById('box').style.color; //獲取 style 對(duì)象中 color 的值

document.getElementById('box').style.color = 'red'; //設(shè)置 style 對(duì)象中 color 的值

document.getElementById('box').className; //獲取 class

document.getElementById('box').className = 'box'; //設(shè)置 class

alert(document.getElementById('box').bbb); //獲取自定義屬性的值,非 IE 不支持

2.getElementsByTagName()方法

getElementsByTagName()方法將返回一個(gè)對(duì)象數(shù)組 HTMLCollection(NodeList),這個(gè)數(shù)

組保存著所有相同元素名的節(jié)點(diǎn)列表。

document.getElementsByTagName('*'); //獲取所有元素

PS:IE 瀏覽器在使用通配符的時(shí)候,會(huì)把文檔最開(kāi)始的 html 的規(guī)范聲明當(dāng)作第一個(gè)元

素節(jié)點(diǎn)。

document.getElementsByTagName('li'); //獲取所有 li 元素,返回?cái)?shù)組

document.getElementsByTagName('li')[0]; //獲取第一個(gè) li 元素,HTMLLIElement

document.getElementsByTagName('li').item(0) //獲取第一個(gè) li 元素,HTMLLIElement

document.getElementsByTagName('li').length; //獲取所有 li 元素的數(shù)目

PS:不管是 getElementById 還是 getElementsByTagName,在傳遞參數(shù)的時(shí)候,并不是

所有瀏覽器都必須區(qū)分大小寫(xiě),為了防止不必要的錯(cuò)誤和麻煩,我們必須堅(jiān)持養(yǎng)成區(qū)分大小

寫(xiě)的習(xí)慣。

3.getElementsByName()方法

getElementsByName()方法可以獲取相同名稱(name)的元素,返回一個(gè)對(duì)象數(shù)組

HTMLCollection(NodeList)。

document.getElementsByName('add') //獲取 input 元素

document.getElementsByName('add')[0].value //獲取 input 元素的 value 值

document.getElementsByName('add')[0].checked //獲取 input 元素的 checked 值

PS:對(duì)于并不是 HTML 合法的屬性,那么在 JS 獲取的兼容性上也會(huì)存在差異,IE 瀏

覽器支持本身合法的 name 屬性,而不合法的就會(huì)出現(xiàn)不兼容的問(wèn)題。

4.getAttribute()方法

getAttribute()方法將獲取元素中某個(gè)屬性的值。它和直接使用.屬性獲取屬性值的方法有

一定區(qū)別。

document.getElementById('box').getAttribute('id');//獲取元素的 id 值

document.getElementById('box').id; //獲取元素的 id 值

document.getElementById('box').getAttribute('mydiv');//獲取元素的自定義屬性值

document.getElementById('box').mydiv //獲取元素的自定義屬性值,非 IE 不支持

document.getElementById('box').getAttribute('class');//獲取元素的 class 值,IE 不支持

document.getElementById('box').getAttribute('className');//非 IE 不支持

PS:HTML 通用屬性 style 和 更低的版本 style 返回一個(gè)對(duì)象,onclick 返回

一個(gè)函數(shù)式。雖然 IE8 已經(jīng)修復(fù)這個(gè) bug,但為了更好的兼容,開(kāi)發(fā)人員只有盡可能避免使

用 getAttribute()訪問(wèn) HTML 屬性了,或者碰到特殊的屬性獲取做特殊的兼容處理。

5.setAttribute()方法

setAttribute()方法將設(shè)置元素中某個(gè)屬性和值。它需要接受兩個(gè)參數(shù):屬性名和值。如

果屬性本身已存在,那么就會(huì)被覆蓋。

document.getElementById('box').setAttribute('align','center');//設(shè)置屬性和值

document.getElementById('box').setAttribute('bbb','ccc');//設(shè)置自定義的屬性和值

PS:在 IE7 及更低的版本中,使用 setAttribute()方法設(shè)置 class 和 style 屬性是沒(méi)有效果

的,雖然 IE8 解決了這個(gè) bug,但還是不建議使用。

6.removeAttribute()方法

removeAttribute()可以移除 HTML 屬性。

document.getElementById('box').removeAttribute('style');//移除屬性

PS:IE6 及更低版本不支持 removeAttribute()方法。


.DOM 節(jié)點(diǎn)

1.node 節(jié)點(diǎn)屬性

節(jié)點(diǎn)可以分為元素節(jié)點(diǎn)、屬性節(jié)點(diǎn)和文本節(jié)點(diǎn),而這些節(jié)點(diǎn)又有三個(gè)非常有用的屬性,

分別為:nodeName、nodeType 和 nodeValue。

document.getElementById('box').nodeType; //1,元素節(jié)點(diǎn)

2.層次節(jié)點(diǎn)屬性

節(jié)點(diǎn)的層次結(jié)構(gòu)可以劃分為:父節(jié)點(diǎn)與子節(jié)點(diǎn)、兄弟節(jié)點(diǎn)這兩種。當(dāng)我們獲取其中一個(gè)

元素節(jié)點(diǎn)的時(shí)候,就可以使用層次節(jié)點(diǎn)屬性來(lái)獲取它相關(guān)層次的節(jié)點(diǎn)

1.childNodes 屬性

childeNodes 屬性可以獲取某一個(gè)元素節(jié)點(diǎn)的所有子節(jié)點(diǎn),這些子節(jié)點(diǎn)包含元素子節(jié)點(diǎn)

和文本子節(jié)點(diǎn)。

var box = document.getElementById('box'); //獲取一個(gè)元素節(jié)點(diǎn)

alert(box.childNodes.length); //獲取這個(gè)元素節(jié)點(diǎn)的所有子節(jié)點(diǎn)

alert(box.childNodes[0]); //獲取第一個(gè)子節(jié)點(diǎn)對(duì)象

PS:使用 childNodes[n]返回子節(jié)點(diǎn)對(duì)象的時(shí)候,有可能返回的是元素子節(jié)點(diǎn),比如

HTMLElement;也有可能返回的是文本子節(jié)點(diǎn),比如 Text。元素子節(jié)點(diǎn)可以使用 nodeName

或者 tagName 獲取標(biāo)簽名稱,而文本子節(jié)點(diǎn)可以使用 nodeValue 獲取。

for (var i = 0; i < box.childNodes.length; i ++) {

//判斷是元素節(jié)點(diǎn),輸出元素標(biāo)簽名

if (box.childNodes[i].nodeType === 1) {

alert('元素節(jié)點(diǎn):' + box.childNodes[i].nodeName);

//判斷是文本節(jié)點(diǎn),輸出文本內(nèi)容

} else if (box.childNodes[i].nodeType === 3) {

alert('文本節(jié)點(diǎn):' + box.childNodes[i].nodeValue);

}

}

PS:在獲取到文本節(jié)點(diǎn)的時(shí)候,是無(wú)法使用 innerHTML 這個(gè)屬性輸出文本內(nèi)容的。這

個(gè)非標(biāo)準(zhǔn)的屬性必須在獲取元素節(jié)點(diǎn)的時(shí)候,才能輸出里面包含的文本。

alert(box.innerHTML); //innerHTML 和 nodeValue 第一個(gè)區(qū)別

PS:innerHTML 和 nodeValue 第一個(gè)區(qū)別,就是取值的。那么第二個(gè)區(qū)別就是賦值的時(shí)

候,nodeValue 會(huì)把包含在文本里的 HTML 轉(zhuǎn)義成特殊字符,從而達(dá)到形成單純文本的效果。

box.childNodes[0].nodeValue = '<strong>abc</strong>';//結(jié)果為:<strong>abc</strong>

box.innerHTML = '<strong>abc</strong>'; //結(jié)果為:abc

2.firstChild 和 lastChild 屬性

firstChild 用于獲取當(dāng)前元素節(jié)點(diǎn)的第一個(gè)子節(jié)點(diǎn),相當(dāng)于 childNodes[0];lastChild 用于

獲取當(dāng)前元素節(jié)點(diǎn)的最后一個(gè)子節(jié)點(diǎn),相當(dāng)于 childNodes[box.childNodes.length - 1]。

alert(box.firstChild.nodeValue); //獲取第一個(gè)子節(jié)點(diǎn)的文本內(nèi)容

alert(box.lastChild.nodeValue); //獲取最后一個(gè)子節(jié)點(diǎn)的文本內(nèi)容

3.ownerDocument 屬性

ownerDocument 屬性返回該節(jié)點(diǎn)的文檔對(duì)象根節(jié)點(diǎn),返回的對(duì)象相當(dāng)于 document。

alert(box.ownerDocument === document); //true,根節(jié)點(diǎn)

4.parentNode、previousSibling、nextSibling 屬性

parentNode 屬性返回該節(jié)點(diǎn)的父節(jié)點(diǎn),previousSibling 屬性返回該節(jié)點(diǎn)的前一個(gè)同級(jí)節(jié)

點(diǎn),nextSibling 屬性返回該節(jié)點(diǎn)的后一個(gè)同級(jí)節(jié)點(diǎn)。

alert(box.parentNode.nodeName); //獲取父節(jié)點(diǎn)的標(biāo)簽名

alert(box.lastChild.previousSibling); //獲取前一個(gè)同級(jí)節(jié)點(diǎn)

alert(box.firstChild.nextSibling); //獲取后一個(gè)同級(jí)節(jié)點(diǎn)

5.attributes 屬性

attributes 屬性返回該節(jié)點(diǎn)的屬性節(jié)點(diǎn)集合。

document.getElementById('box').attributes //NamedNodeMap

document.getElementById('box').attributes.length;//返回屬性節(jié)點(diǎn)個(gè)數(shù)

document.getElementById('box').attributes[0]; //Attr,返回最后一個(gè)屬性節(jié)點(diǎn)

document.getElementById('box').attributes[0].nodeType; //2,節(jié)點(diǎn)類(lèi)型

document.getElementById('box').attributes[0].nodeValue; //屬性值

document.getElementById('box').attributes['id']; //Attr,返回屬性為 id 的節(jié)點(diǎn)

document.getElementById('box').attributes.getNamedItem('id'); //Attr

6.忽略空白文本節(jié)點(diǎn)

var body = document.getElementsByTagName('body')[0];//獲取 body 元素節(jié)點(diǎn)

alert(body.childNodes.length); //得到子節(jié)點(diǎn)個(gè)數(shù),IE3 個(gè),非 IE7 個(gè)

PS:在非 IE 中,標(biāo)準(zhǔn)的 DOM 具有識(shí)別空白文本節(jié)點(diǎn)的功能,所以在火狐瀏覽器是 7

個(gè),而 IE 自動(dòng)忽略了,如果要保持一致的子元素節(jié)點(diǎn),需要手工忽略掉它。

function filterSpaceNode(nodes) {

var ret = []; //新數(shù)組

for (var i = 0; i < nodes.length; i ++) {

//如果識(shí)別到空白文本節(jié)點(diǎn),就不添加數(shù)組

if (nodes[i].nodeType == 3 && /^\s+$/.test(nodes[i].nodeValue)) continue;

//把每次的元素節(jié)點(diǎn),添加到數(shù)組里

ret.push(nodes[i]);

}

return ret;

}

PS:上面的方法,采用的忽略空白文件節(jié)點(diǎn)的方法,把得到元素節(jié)點(diǎn)累加到數(shù)組里返

回。那么還有一種做法是,直接刪除空白節(jié)點(diǎn)即可。

function filterSpaceNode(nodes) {

for (var i = 0; i < nodes.length; i ++) {

if (nodes[i].nodeType == 3 && /^\s+$/.test(nodes[i].nodeValue)) {

//得到空白節(jié)點(diǎn)之后,移到父節(jié)點(diǎn)上,刪除子節(jié)點(diǎn)

nodes[i].parentNode.removeChild(nodes[i]);

}

}

return nodes;

}

PS:如果 firstChild、lastChild、previousSibling 和 nextSibling 在獲取節(jié)點(diǎn)的過(guò)程中遇到

空白節(jié)點(diǎn),我們?cè)撛趺刺幚淼裟兀?/p>

function removeWhiteNode(nodes) {

for (var i = 0; i < nodes.childNodes.length; i ++) {

if (nodes.childNodes[i].nodeType === 3 &&

/^\s+$/.test(nodes.childNodes[i].nodeValue)) {

nodes.childNodes[i].parentNode.removeChild(nodes.childNodes[i]);

}

}

return nodes;

}



節(jié)點(diǎn)操作

DOM 不單單可以查找節(jié)點(diǎn),也可以創(chuàng)建節(jié)點(diǎn)、復(fù)制節(jié)點(diǎn)、插入節(jié)點(diǎn)、刪除節(jié)點(diǎn)和替換

節(jié)點(diǎn)

1.write()方法

write()方法可以把任意字符串插入到文檔中去。

document.write('<p>這是一個(gè)段落!</p>')'; //輸出任意字符串

2.createElement()方法

createElement()方法可以創(chuàng)建一個(gè)元素節(jié)點(diǎn)。

document.createElement('p'); //創(chuàng)建一個(gè)元素節(jié)點(diǎn)

3.appendChild()方法

appendChild()方法講一個(gè)新節(jié)點(diǎn)添加到某個(gè)節(jié)點(diǎn)的子節(jié)點(diǎn)列表的末尾上。

var box = document.getElementById('box'); //獲取某一個(gè)元素節(jié)點(diǎn)

var p = document.createElement('p'); //創(chuàng)建一個(gè)新元素節(jié)點(diǎn)<p>

box.appendChild(p); //把新元素節(jié)點(diǎn)<p>添加子節(jié)點(diǎn)末尾

4.createTextNode()方法

createTextNode()方法創(chuàng)建一個(gè)文本節(jié)點(diǎn)。

var text = document.createTextNode('段落'); //創(chuàng)建一個(gè)文本節(jié)點(diǎn)

p.appendChild(text); //將文本節(jié)點(diǎn)添加到子節(jié)點(diǎn)末尾

5.insertBefore()方法

insertBefore()方法可以把節(jié)點(diǎn)創(chuàng)建到指定節(jié)點(diǎn)的前面。

box.parentNode.insertBefore(p, box); //把<div>之前創(chuàng)建一個(gè)節(jié)點(diǎn)

PS:insertBefore()方法可以給當(dāng)前元素的前面創(chuàng)建一個(gè)節(jié)點(diǎn),但卻沒(méi)有提供給當(dāng)前元素

的后面創(chuàng)建一個(gè)節(jié)點(diǎn)。那么,我們可以用已有的知識(shí)創(chuàng)建一個(gè) insertAfter()函數(shù)。

function insertAfter(newElement, targetElement) {

//得到父節(jié)點(diǎn)

var parent = targetElement.parentNode;

//如果最后一個(gè)子節(jié)點(diǎn)是當(dāng)前元素,那么直接添加即可

if (parent.lastChild === targetElement) {

parent.appendChild(newElement);

} else {

//否則,在當(dāng)前節(jié)點(diǎn)的下一個(gè)節(jié)點(diǎn)之前添加

parent.insertBefore(newElement, targetElement.nextSibling);

}

}

PS:createElement 在創(chuàng)建一般元素節(jié)點(diǎn)的時(shí)候,瀏覽器的兼容性都還比較好。但在幾

個(gè)特殊標(biāo)簽上,比如 iframe、input 中的 radio 和 checkbox、button 元素中,可能會(huì)在 IE6,7

以下的瀏覽器存在一些不兼容。

var input = null;

if (BrowserDetect.browser == 'Internet Explorer' && BrowserDetect.version <= 7) {

//判斷 IE6,7,使用字符串的方式

input = document.createElement("<input type=\"radio\" name=\"sex\">");

} else {

//標(biāo)準(zhǔn)瀏覽器,使用標(biāo)準(zhǔn)方式

input = document.createElement('input');

input.setAttribute('type', 'radio');

input.setAttribute('name', 'sex');

}

document.getElementsByTagName('body')[0].appendChild(input);

6.repalceChild()方法

replaceChild()方法可以把節(jié)點(diǎn)替換成指定的節(jié)點(diǎn)。

box.parentNode.replaceChild(p,box); //把<div>換成了<p>

7.cloneNode()方法

cloneNode()方法可以把子節(jié)點(diǎn)復(fù)制出來(lái)。

var box = document.getElementById('box');

var clone = box.firstChild.cloneNode(true); //獲取第一個(gè)子節(jié)點(diǎn),true 表示復(fù)制內(nèi)容

box.appendChild(clone); //添加到子節(jié)點(diǎn)列表末尾

8.removeChild()方法

removeChild()方法可以把

box.parentNode.removeChild(box); //刪除指定節(jié)點(diǎn)


向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI