Javascript操作DOM常用API總結(jié)

原文地址:http://luopq.com/2015/11/30/javascript-dom/

文本整理了javascript操作DOM的一些常用的api日缨,根據(jù)其作用整理成為創(chuàng)建,修改掖看,查詢等多種類型的api匣距,主要用于復(fù)習(xí)基礎(chǔ)知識(shí),加深對(duì)原生js的認(rèn)識(shí)哎壳。

基本概念

在講解操作DOM的api之前毅待,首先我們來(lái)復(fù)習(xí)一下一些基本概念,這些概念是掌握api的關(guān)鍵归榕,必須理解它們尸红。

Node類型

DOM1級(jí)定義了一個(gè)Node接口,該接口由DOM中所有節(jié)點(diǎn)類型實(shí)現(xiàn)刹泄。這個(gè)Node接口在JS中是作為Node類型實(shí)現(xiàn)的外里。在IE9以下版本無(wú)法訪問(wèn)到這個(gè)類型,JS中所有節(jié)點(diǎn)都繼承自Node類型特石,都共享著相同的基本屬性和方法盅蝗。
Node有一個(gè)屬性nodeType表示Node的類型,它是一個(gè)整數(shù)姆蘸,其數(shù)值分別表示相應(yīng)的Node類型墩莫,具體如下:

  • Node.element_node:1
  • Node.attribute_node:2
  • Node.text_node:3
  • Node.cdata_section_node:4
  • Node.entity_reference_node:5
  • Node.entity_node:6
  • Node.precessing_instruction_node:7
  • Node.comment_node:8
  • Node.document_node:9
  • Node.document_type_node:10
  • Node.document_fragment_node:11
  • Node.notation_node:12
    假設(shè)我們要判斷一個(gè)Node是不是元素,我們可以這樣判斷
if(someNode.nodeType==1){
  console.log("Node is a element");
}

這些Node類型中逞敷,我們最常用的就是element狂秦,text,attribute推捐,comment裂问,document,document_fragment這幾種類型牛柒。
我們簡(jiǎn)單來(lái)介紹一下這幾種類型:

Element類型

Element提供了對(duì)元素標(biāo)簽名堪簿,子節(jié)點(diǎn)和特性的訪問(wèn),我們常用HTML元素比如div焰络,span戴甩,a等標(biāo)簽就是element中的一種。Element有下面幾條特性:
(1)nodeType為1
(2)nodeName為元素標(biāo)簽名闪彼,tagName也是返回標(biāo)簽名
(3)nodeValue為null
(4)parentNode可能是Document或Element
(5)子節(jié)點(diǎn)可能是Element甜孤,Text协饲,Comment,Processing_Instruction缴川,CDATASection或EntityReference

Text類型

Text表示文本節(jié)點(diǎn)茉稠,它包含的是純文本內(nèi)容,不能包含html代碼把夸,但可以包含轉(zhuǎn)義后的html代碼而线。Text有下面的特性:
(1)nodeType為3
(2)nodeName為#text
(3)nodeValue為文本內(nèi)容
(4)parentNode是一個(gè)Element
(5)沒(méi)有子節(jié)點(diǎn)

Attr類型

Attr類型表示元素的特性,相當(dāng)于元素的attributes屬性中的節(jié)點(diǎn)恋日,它有下面的特性:
(1)nodeType值為2
(2)nodeName是特性的名稱
(3)nodeValue是特性的值
(4)parentNode為null

Comment類型

Comment表示HTML文檔中的注釋膀篮,它有下面的幾種特征:
(1)nodeType為8
(2)nodeName為#comment
(3)nodeValue為注釋的內(nèi)容
(4)parentNode可能是Document或Element
(5)沒(méi)有子節(jié)點(diǎn)

Document

Document表示文檔,在瀏覽器中岂膳,document對(duì)象是HTMLDocument的一個(gè)實(shí)例誓竿,表示整個(gè)頁(yè)面,它同時(shí)也是window對(duì)象的一個(gè)屬性谈截。Document有下面的特性:
(1)nodeType為9
(2)nodeName為#document
(3)nodeValue為null
(4)parentNode為null
(5)子節(jié)點(diǎn)可能是一個(gè)DocumentType或Element

DocumentFragment類型

DocumentFragment是所有節(jié)點(diǎn)中唯一一個(gè)沒(méi)有對(duì)應(yīng)標(biāo)記的類型筷屡,它表示一種輕量級(jí)的文檔,可能當(dāng)作一個(gè)臨時(shí)的倉(cāng)庫(kù)用來(lái)保存可能會(huì)添加到文檔中的節(jié)點(diǎn)簸喂。DocumentFragment有下面的特性:
(1)nodeType為11
(2)nodeName為#document-fragment
(3)nodeValue為null
(4)parentNode為null

我們簡(jiǎn)單地介紹了幾種常見(jiàn)的Node類型毙死,要記住,HTML中的節(jié)點(diǎn)并不只是包括元素節(jié)點(diǎn)喻鳄,它還包括文本節(jié)點(diǎn)扼倘,注釋節(jié)點(diǎn)等等。在這里我們只是簡(jiǎn)單地說(shuō)明了幾種常見(jiàn)的節(jié)點(diǎn)诽表,想要進(jìn)一步學(xué)習(xí)的同學(xué)可以查找一下相關(guān)資料唉锌。

節(jié)點(diǎn)創(chuàng)建型api

在這里隅肥,我將常用的DOM操作api進(jìn)行分類竿奏,首先要介紹的是創(chuàng)建型的api原献。這一類型的api霜威,簡(jiǎn)而言之就是用來(lái)創(chuàng)建節(jié)點(diǎn)的。

createElement

createElement通過(guò)傳入指定的一個(gè)標(biāo)簽名來(lái)創(chuàng)建一個(gè)元素属百,如果傳入的標(biāo)簽名是一個(gè)未知的秃症,則會(huì)創(chuàng)建一個(gè)自定義的標(biāo)簽候址,注意:IE8以下瀏覽器不支持自定義標(biāo)簽。
使用如下:

var div = document.createElement("div");

使用createElement要注意:通過(guò)createElement創(chuàng)建的元素并不屬于html文檔种柑,它只是創(chuàng)建出來(lái)岗仑,并未添加到html文檔中,要調(diào)用appendChild或insertBefore等方法將其添加到HTML文檔樹中聚请。

cloneNode

cloneNode是用來(lái)返回調(diào)用方法的節(jié)點(diǎn)的一個(gè)副本荠雕,它接收一個(gè)bool參數(shù)稳其,用來(lái)表示是否復(fù)制子元素,使用如下:

var parent = document.getElementById("parentElement"); 
var parent2 = parent.cloneNode(true);// 傳入true
parent2.id = "parent2";

這段代碼通過(guò)cloneNode復(fù)制了一份parent元素炸卑,其中cloneNode的參數(shù)為true既鞠,表示parent的子節(jié)點(diǎn)也被復(fù)制,如果傳入false盖文,則表示只復(fù)制了parent節(jié)點(diǎn)嘱蛋。
我們看看這個(gè)例子

<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);
}

這段代碼很簡(jiǎn)單,主要是綁定button事件五续,事件內(nèi)容是復(fù)制了一個(gè)parent洒敏,修改其id,然后添加到文檔中疙驾。
這里有幾點(diǎn)要注意:
(1)和createElement一樣桐玻,cloneNode創(chuàng)建的節(jié)點(diǎn)只是游離有html文檔外的節(jié)點(diǎn),要調(diào)用appendChild方法才能添加到文檔樹中
(2)如果復(fù)制的元素有id荆萤,則其副本同樣會(huì)包含該id镊靴,由于id具有唯一性,所以在復(fù)制節(jié)點(diǎn)后必須要修改其id
(3)調(diào)用接收的bool參數(shù)最好傳入链韭,如果不傳入該參數(shù)偏竟,不同瀏覽器對(duì)其默認(rèn)值的處理可能不同

除此之外,我們還有一個(gè)需要注意的點(diǎn):
如果被復(fù)制的節(jié)點(diǎn)綁定了事件敞峭,則副本也會(huì)跟著綁定該事件嗎踊谋?這里要分情況討論:
(1)如果是通過(guò)addEventListener或者比如onclick進(jìn)行綁定事件,則副本節(jié)點(diǎn)不會(huì)綁定該事件
(2)如果是內(nèi)聯(lián)方式綁定比如

<div onclick="showParent()"></div>

這樣的話旋讹,副本節(jié)點(diǎn)同樣會(huì)觸發(fā)事件殖蚕。

createDocumentFragment

createDocumentFragment方法用來(lái)創(chuàng)建一個(gè)DocumentFragment。在前面我們說(shuō)到DocumentFragment表示一種輕量級(jí)的文檔沉迹,它的作用主要是存儲(chǔ)臨時(shí)的節(jié)點(diǎn)用來(lái)準(zhǔn)備添加到文檔中睦疫。
createDocumentFragment方法主要是用于添加大量節(jié)點(diǎn)到文檔中時(shí)會(huì)使用到。假設(shè)要循環(huán)一組數(shù)據(jù)鞭呕,然后創(chuàng)建多個(gè)節(jié)點(diǎn)添加到文檔中蛤育,比如示例

<ul id="list"></ul>
<input type="button" value="添加多項(xiàng)" 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);
    }
}

這段代碼將按鈕綁定了一個(gè)事件,這個(gè)事件創(chuàng)建了100個(gè)li節(jié)點(diǎn)葫松,然后依次將其添加HTML文檔中瓦糕。這樣做有一個(gè)缺點(diǎn):每次一創(chuàng)建一個(gè)新的元素,然后添加到文檔樹中腋么,這個(gè)過(guò)程會(huì)造成瀏覽器的回流咕娄。所謂回流簡(jiǎn)單說(shuō)就是指元素大小和位置會(huì)被重新計(jì)算,如果添加的元素太多珊擂,會(huì)造成性能問(wèn)題圣勒。這個(gè)時(shí)候徐块,就是使用createDocumentFragment了。
DocumentFragment不是文檔樹的一部分灾而,它是保存在內(nèi)存中的胡控,所以不會(huì)造成回流問(wèn)題。我們修改上面的代碼如下:

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)建了一個(gè)fragment旁趟,每次生成的li節(jié)點(diǎn)先添加到fragment昼激,最后一次性添加到list,大家可以看示例

創(chuàng)建型API總結(jié)

創(chuàng)建型api主要包括createElement锡搜,createTextNode橙困,cloneNode和createDocumentFragment四個(gè)方法,需要注意下面幾點(diǎn):
(1)它們創(chuàng)建的節(jié)點(diǎn)只是一個(gè)孤立的節(jié)點(diǎn)耕餐,要通過(guò)appendChild添加到文檔中
(2)cloneNode要注意如果被復(fù)制的節(jié)點(diǎn)是否包含子節(jié)點(diǎn)以及事件綁定等問(wèn)題
(3)使用createDocumentFragment來(lái)解決添加大量節(jié)點(diǎn)時(shí)的性能問(wèn)題

頁(yè)面修改型API

前面我們提到創(chuàng)建型api凡傅,它們只是創(chuàng)建節(jié)點(diǎn),并沒(méi)有真正修改到頁(yè)面內(nèi)容肠缔,而是要調(diào)用appendChild來(lái)將其添加到文檔樹中夏跷。我在這里將這類會(huì)修改到頁(yè)面內(nèi)容歸為一類。
修改頁(yè)面內(nèi)容的api主要包括:appendChild明未,insertBefore槽华,removeChild,replaceChild趟妥。

appendChild

appendChild我們?cè)谇懊嬉呀?jīng)用到多次猫态,就是將指定的節(jié)點(diǎn)添加到調(diào)用該方法的節(jié)點(diǎn)的子元素的末尾。調(diào)用方法如下:

parent.appendChild(child);

child節(jié)點(diǎn)將會(huì)作為parent節(jié)點(diǎn)的最后一個(gè)子節(jié)點(diǎn)披摄。
appendChild這個(gè)方法很簡(jiǎn)單亲雪,但是還有有一點(diǎn)需要注意:如果被添加的節(jié)點(diǎn)是一個(gè)頁(yè)面中存在的節(jié)點(diǎn),則執(zhí)行后這個(gè)節(jié)點(diǎn)將會(huì)添加到指定位置疚膊,其原本所在的位置將移除該節(jié)點(diǎn)义辕,也就是說(shuō)不會(huì)同時(shí)存在兩個(gè)該節(jié)點(diǎn)在頁(yè)面上,相當(dāng)于把這個(gè)節(jié)點(diǎn)移動(dòng)到另一個(gè)地方酿联。我們來(lái)看例子

<div id="child">
    要被添加的節(jié)點(diǎn)
</div>
<br/>
<br/>
<br/>
<div id="parent">
    要移動(dòng)的位置
</div>      
<input id="btnMove" type="button" value="移動(dòng)節(jié)點(diǎn)" />

document.getElementById("btnMove").onclick = function(){
    var child = document.getElementById("child");
    document.getElementById("parent").appendChild(child);
}

這段代碼主要是獲取頁(yè)面上的child節(jié)點(diǎn)终息,然后添加到指定位置,可以看到原本的child節(jié)點(diǎn)被移動(dòng)到parent中了贞让。
這里還有一個(gè)要注意的點(diǎn):如果child綁定了事件,被移動(dòng)時(shí)柳譬,它依然綁定著該事件喳张。

insertBefore

insertBefore用來(lái)添加一個(gè)節(jié)點(diǎn)到一個(gè)參照節(jié)點(diǎn)之前,用法如下:

parentNode.insertBefore(newNode,refNode);

parentNode表示新節(jié)點(diǎn)被添加后的父節(jié)點(diǎn)
newNode表示要添加的節(jié)點(diǎn)
refNode表示參照節(jié)點(diǎn)美澳,新節(jié)點(diǎn)會(huì)添加到這個(gè)節(jié)點(diǎn)之前
我們來(lái)看這個(gè)例子

<div id="parent">
    父節(jié)點(diǎn)
    <div id="child">                
        子元素
    </div>
</div>
<input type="button" id="insertNode" value="插入節(jié)點(diǎn)" />

var parent = document.getElementById("parent");
var child = document.getElementById("child");
document.getElementById("insertNode").onclick = function(){
    var newNode = document.createElement("div");
    newNode.textContent = "新節(jié)點(diǎn)"
    parent.insertBefore(newNode,child);
}

這段代碼創(chuàng)建了一個(gè)新節(jié)點(diǎn)销部,然后添加到child節(jié)點(diǎn)之前摸航。
和appendChild一樣,如果插入的節(jié)點(diǎn)是頁(yè)面上的節(jié)點(diǎn)舅桩,則會(huì)移動(dòng)該節(jié)點(diǎn)到指定位置酱虎,并且保留其綁定的事件。

關(guān)于第二個(gè)參數(shù)參照節(jié)點(diǎn)還有幾個(gè)注意的地方:
(1)refNode是必傳的擂涛,如果不傳該參數(shù)會(huì)報(bào)錯(cuò)
(2)如果refNode是undefined或null读串,則insertBefore會(huì)將節(jié)點(diǎn)添加到子元素的末尾

removeChild

removeChild顧名思義,就是刪除指定的子節(jié)點(diǎn)并返回撒妈,用法如下:

var deletedChild = parent.removeChild(node);

deletedChild指向被刪除節(jié)點(diǎn)的引用恢暖,它等于node,被刪除的節(jié)點(diǎn)仍然存在于內(nèi)存中狰右,可以對(duì)其進(jìn)行下一步操作杰捂。
注意:如果被刪除的節(jié)點(diǎn)不是其子節(jié)點(diǎn),則程序?qū)?huì)報(bào)錯(cuò)棋蚌。我們可以通過(guò)下面的方式來(lái)確奔藜眩可以刪除:

if(node.parentNode){
    node.parentNode.removeChild(node);
}

通過(guò)節(jié)點(diǎn)自己獲取節(jié)點(diǎn)的父節(jié)點(diǎn),然后將自身刪除谷暮。

replaceChild

replaceChild用于使用一個(gè)節(jié)點(diǎn)替換另一個(gè)節(jié)點(diǎn)脱拼,用法如下

parent.replaceChild(newChild,oldChild);

newChild是替換的節(jié)點(diǎn),可以是新的節(jié)點(diǎn)坷备,也可以是頁(yè)面上的節(jié)點(diǎn)熄浓,如果是頁(yè)面上的節(jié)點(diǎn),則其將被轉(zhuǎn)移到新的位置
oldChild是被替換的節(jié)點(diǎn)

頁(yè)面修改型API總結(jié)

頁(yè)面修改型api主要是這四個(gè)接口省撑,要注意幾個(gè)特點(diǎn):
(1)不管是新增還是替換節(jié)點(diǎn)赌蔑,如果新增或替換的節(jié)點(diǎn)是原本存在頁(yè)面上的,則其原來(lái)位置的節(jié)點(diǎn)將被移除竟秫,也就是說(shuō)同一個(gè)節(jié)點(diǎn)不能存在于頁(yè)面的多個(gè)位置
(2)節(jié)點(diǎn)本身綁定的事件會(huì)不會(huì)消失娃惯,會(huì)一直保留著。

節(jié)點(diǎn)查詢型API

節(jié)點(diǎn)查詢型API也是非常常用的api肥败,下面我們分別說(shuō)明一下每一個(gè)api的使用趾浅。

document.getElementById

這個(gè)接口很簡(jiǎn)單,根據(jù)元素id返回元素馒稍,返回值是Element類型皿哨,如果不存在該元素,則返回null纽谒。
使用這個(gè)接口有幾點(diǎn)要注意:
(1)元素的Id是大小寫敏感的证膨,一定要寫對(duì)元素的id
(2)HTML文檔中可能存在多個(gè)id相同的元素,則返回第一個(gè)元素
(3)只從文檔中進(jìn)行搜索元素鼓黔,如果創(chuàng)建了一個(gè)元素并指定id央勒,但并沒(méi)有添加到文檔中不见,則這個(gè)元素是不會(huì)被查找到的

document.getElementsByTagName

這個(gè)接口根據(jù)元素標(biāo)簽名獲取元素,返回一個(gè)即時(shí)的HTMLCollection類型崔步,什么是即時(shí)的HTMLCollection類型呢稳吮?我們來(lái)看看這個(gè)示例

<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);
}

這段代碼中有兩個(gè)按鈕,一個(gè)按鈕是顯示HTMLCollection元素的個(gè)數(shù)井濒,另一個(gè)按鈕可以新增一個(gè)div標(biāo)簽到文檔中灶似。前面提到HTMLCollcetion元素是即時(shí)的表示該集合是隨時(shí)變化的,也就是是文檔中有幾個(gè)div眼虱,它會(huì)隨時(shí)進(jìn)行變化喻奥,當(dāng)我們新增一個(gè)div后,再訪問(wèn)HTMLCollection時(shí)捏悬,就會(huì)包含這個(gè)新增的div撞蚕。
使用document.getElementsByTagName這個(gè)方法有幾點(diǎn)要注意:
(1)如果要對(duì)HTMLCollection集合進(jìn)行循環(huán)操作,最好將其長(zhǎng)度緩存起來(lái)过牙,因?yàn)槊看窝h(huán)都會(huì)去計(jì)算長(zhǎng)度甥厦,暫時(shí)緩存起來(lái)可以提高效率
(2)如果沒(méi)有存在指定的標(biāo)簽,該接口返回的不是null寇钉,而是一個(gè)空的HTMLCollection
(3)“*”表示所有標(biāo)簽

document.getElementsByName

getElementsByName主要是通過(guò)指定的name屬性來(lái)獲取元素刀疙,它返回一個(gè)即時(shí)的NodeList對(duì)象。
使用這個(gè)接口主要要注意幾點(diǎn):
(1)返回對(duì)象是一個(gè)即時(shí)的NodeList扫倡,它是隨時(shí)變化的
(2)在HTML元素中谦秧,并不是所有元素都有name屬性,比如div是沒(méi)有name屬性的撵溃,但是如果強(qiáng)制設(shè)置div的name屬性疚鲤,它也是可以被查找到的
(3)在IE中,如果id設(shè)置成某個(gè)值缘挑,然后傳入getElementsByName的參數(shù)值和id值一樣集歇,則這個(gè)元素是會(huì)被找到的,所以最好不好設(shè)置同樣的值給id和name

document.getElementsByClassName

這個(gè)API是根據(jù)元素的class返回一個(gè)即時(shí)的HTMLCollection语淘,用法如下

var elements = document.getElementsByClassName(names);

這個(gè)接口有下面幾點(diǎn)要注意:
(1)返回結(jié)果是一個(gè)即時(shí)的HTMLCollection诲宇,會(huì)隨時(shí)根據(jù)文檔結(jié)構(gòu)變化
(2)IE9以下瀏覽器不支持
(3)如果要獲取2個(gè)以上classname,可傳入多個(gè)classname惶翻,每個(gè)用空格相隔姑蓝,例如

var elements = document.getElementsByClassName("test1 test2");
document.querySelector和document.querySelectorAll

這兩個(gè)api很相似,通過(guò)css選擇器來(lái)查找元素维贺,注意選擇器要符合CSS選擇器的規(guī)則它掂。
首先來(lái)介紹一下document.querySelector。
document.querySelector返回第一個(gè)匹配的元素溯泣,如果沒(méi)有匹配的元素虐秋,則返回null。
注意垃沦,由于返回的是第一個(gè)匹配的元素客给,這個(gè)api使用的深度優(yōu)先搜索來(lái)獲取元素。我們來(lái)看這個(gè)例子

<div>
    <div>
        <span class="test">第三級(jí)的span</span>  
    </div>
</div>
<div class="test">          
    同級(jí)的第二個(gè)div
</div>
<input type="button" id="btnGet" value="獲取test元素" />

document.getElementById("btnGet").addEventListener("click",function(){
    var element = document.querySelector(".test");
    alert(element.textContent);
})

這個(gè)例子很簡(jiǎn)單肢簿,就是兩個(gè)class都包含“test”的元素靶剑,一個(gè)在文檔樹的前面,但是它在第三級(jí)池充,另一個(gè)在文檔樹的后面桩引,但它在第一級(jí),通過(guò)querySelector獲取元素時(shí)收夸,它通過(guò)深度優(yōu)先搜索坑匠,拿到文檔樹前面的第三級(jí)的元素。

document.querySelectorAll的不同之處在于它返回的是所有匹配的元素卧惜,而且可以匹配多個(gè)選擇符厘灼,我們來(lái)看看下面這個(gè)例子

<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);
    }   
})

這段代碼通過(guò)querySelectorAll,使用id選擇器和class選擇器選擇了兩個(gè)元素咽瓷,并依次輸出其內(nèi)容设凹。要注意兩點(diǎn):
(1)querySelectorAll也是通過(guò)深度優(yōu)先搜索,搜索的元素順序和選擇器的順序無(wú)關(guān)
(2)返回的是一個(gè)非即時(shí)的NodeList茅姜,也就是說(shuō)結(jié)果不會(huì)隨著文檔樹的變化而變化

兼容性問(wèn)題:querySelector和querySelectorAll在ie8以下的瀏覽器不支持闪朱。

節(jié)點(diǎn)關(guān)系型api

在html文檔中的每個(gè)節(jié)點(diǎn)之間的關(guān)系都可以看成是家譜關(guān)系,包含父子關(guān)系钻洒,兄弟關(guān)系等等奋姿,下面我們依次來(lái)看看每一種關(guān)系。

父關(guān)系型api

parentNode:每個(gè)節(jié)點(diǎn)都有一個(gè)parentNode屬性航唆,它表示元素的父節(jié)點(diǎn)胀蛮。Element的父節(jié)點(diǎn)可能是Element,Document或DocumentFragment糯钙。
parentElement:返回元素的父元素節(jié)點(diǎn)粪狼,與parentNode的區(qū)別在于,其父節(jié)點(diǎn)必須是一個(gè)Element任岸,如果不是再榄,則返回null

兄弟關(guān)系型api

previousSibling:節(jié)點(diǎn)的前一個(gè)節(jié)點(diǎn),如果該節(jié)點(diǎn)是第一個(gè)節(jié)點(diǎn)享潜,則為null困鸥。注意有可能拿到的節(jié)點(diǎn)是文本節(jié)點(diǎn)或注釋節(jié)點(diǎn),與預(yù)期的不符,要進(jìn)行處理一下疾就。
previousElementSibling:返回前一個(gè)元素節(jié)點(diǎn)澜术,前一個(gè)節(jié)點(diǎn)必須是Element,注意IE9以下瀏覽器不支持猬腰。

nextSibling:節(jié)點(diǎn)的后一個(gè)節(jié)點(diǎn)鸟废,如果該節(jié)點(diǎn)是最后一個(gè)節(jié)點(diǎn),則為null姑荷。注意有可能拿到的節(jié)點(diǎn)是文本節(jié)點(diǎn)盒延,與預(yù)期的不符,要進(jìn)行處理一下鼠冕。
nextElementSibling:返回后一個(gè)元素節(jié)點(diǎn)添寺,后一個(gè)節(jié)點(diǎn)必須是Element,注意IE9以下瀏覽器不支持懈费。

子關(guān)系型api

childNodes:返回一個(gè)即時(shí)的NodeList计露,表示元素的子節(jié)點(diǎn)列表,子節(jié)點(diǎn)可能會(huì)包含文本節(jié)點(diǎn)楞捂,注釋節(jié)點(diǎn)等薄坏。
children:一個(gè)即時(shí)的HTMLCollection,子節(jié)點(diǎn)都是Element寨闹,IE9以下瀏覽器不支持胶坠。
firstNode:第一個(gè)子節(jié)點(diǎn)
lastNode:最后一個(gè)子節(jié)點(diǎn)
hasChildNodes方法:可以用來(lái)判斷是否包含子節(jié)點(diǎn)。

元素屬性型api

setAttribute

setAttribute:根據(jù)名稱和值修改元素的特性繁堡,用法如下沈善。

element.setAttribute(name, value);

其中name是特性名,value是特性值椭蹄。如果元素不包含該特性闻牡,則會(huì)創(chuàng)建該特性并賦值。
如果元素本身包含指定的特性名為屬性绳矩,則可以世界訪問(wèn)屬性進(jìn)行賦值罩润,比如下面兩條代碼是等價(jià)的:

element.setAttribute("id","test");

element.id = "test";
getAttribute

getAttribute返回指定的特性名相應(yīng)的特性值,如果不存在翼馆,則返回null或空字符串割以。用法如下:

var value = element.getAttribute("id");

元素樣式型api

window.getComputedStyle

window.getComputedStyle是用來(lái)獲取應(yīng)用到元素后的樣式,假設(shè)某個(gè)元素并未設(shè)置高度而是通過(guò)其內(nèi)容將其高度撐開应媚,這時(shí)候要獲取它的高度就要用到getComputedStyle严沥,用法如下:

var style = window.getComputedStyle(element[, pseudoElt]);

element是要獲取的元素,pseudoElt指定一個(gè)偽元素進(jìn)行匹配中姜。
返回的style是一個(gè)CSSStyleDeclaration對(duì)象消玄。
通過(guò)style可以訪問(wèn)到元素計(jì)算后的樣式

getBoundingClientRect

getBoundingClientRect用來(lái)返回元素的大小以及相對(duì)于瀏覽器可視窗口的位置,用法如下:

var clientRect = element.getBoundingClientRect();

clientRect是一個(gè)DOMRect對(duì)象,包含left翩瓜,top受扳,right,bottom奥溺,它是相對(duì)于可視窗口的距離辞色,滾動(dòng)位置發(fā)生改變時(shí)骨宠,它們的值是會(huì)發(fā)生變化的浮定。除了IE9以下瀏覽器,還包含元素的height和width等數(shù)據(jù)层亿,具體可查看鏈接

總結(jié)

本文主要總結(jié)了原生js中常用的操作DOM的api接口桦卒,主要為了復(fù)習(xí)基礎(chǔ)知識(shí)。平時(shí)開發(fā)用多了jQuery等類庫(kù)匿又,對(duì)基礎(chǔ)知識(shí)的了解可能就漸漸地遺忘方灾,但這些基礎(chǔ)知識(shí)才是我們立足的根本,只有掌握原生的js碌更,才能真正做好js的開發(fā)裕偿。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市痛单,隨后出現(xiàn)的幾起案子嘿棘,更是在濱河造成了極大的恐慌,老刑警劉巖旭绒,帶你破解...
    沈念sama閱讀 221,273評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鸟妙,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡挥吵,警方通過(guò)查閱死者的電腦和手機(jī)重父,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)忽匈,“玉大人房午,你說(shuō)我怎么就攤上這事〉ぴ剩” “怎么了郭厌?”我有些...
    開封第一講書人閱讀 167,709評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)嫌松。 經(jīng)常有香客問(wèn)我沪曙,道長(zhǎng),這世上最難降的妖魔是什么萎羔? 我笑而不...
    開封第一講書人閱讀 59,520評(píng)論 1 296
  • 正文 為了忘掉前任液走,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘缘眶。我一直安慰自己嘱根,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,515評(píng)論 6 397
  • 文/花漫 我一把揭開白布巷懈。 她就那樣靜靜地躺著该抒,像睡著了一般。 火紅的嫁衣襯著肌膚如雪顶燕。 梳的紋絲不亂的頭發(fā)上凑保,一...
    開封第一講書人閱讀 52,158評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音涌攻,去河邊找鬼欧引。 笑死,一個(gè)胖子當(dāng)著我的面吹牛恳谎,可吹牛的內(nèi)容都是我干的芝此。 我是一名探鬼主播,決...
    沈念sama閱讀 40,755評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼因痛,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼婚苹!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起鸵膏,我...
    開封第一講書人閱讀 39,660評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤膊升,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后较性,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體用僧,經(jīng)...
    沈念sama閱讀 46,203評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,287評(píng)論 3 340
  • 正文 我和宋清朗相戀三年赞咙,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了责循。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,427評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡攀操,死狀恐怖院仿,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情速和,我是刑警寧澤歹垫,帶...
    沈念sama閱讀 36,122評(píng)論 5 349
  • 正文 年R本政府宣布,位于F島的核電站颠放,受9級(jí)特大地震影響排惨,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜碰凶,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,801評(píng)論 3 333
  • 文/蒙蒙 一暮芭、第九天 我趴在偏房一處隱蔽的房頂上張望鹿驼。 院中可真熱鬧,春花似錦辕宏、人聲如沸畜晰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,272評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)凄鼻。三九已至,卻和暖如春聚假,著一層夾襖步出監(jiān)牢的瞬間块蚌,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工魔策, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留匈子,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,808評(píng)論 3 376
  • 正文 我出身青樓闯袒,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親游岳。 傳聞我的和親對(duì)象是個(gè)殘疾皇子政敢,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,440評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • Node類型 DOM1級(jí)定義了一個(gè)Node接口,該接口由DOM中所有節(jié)點(diǎn)類型實(shí)現(xiàn)胚迫。這個(gè)Node接口在JS中是作為N...
    Maggie_77閱讀 422評(píng)論 0 0
  • 什么是DOM喷户??访锻? DOM(Document Object Model 文檔對(duì)象模型)是針對(duì)HTML和XML文檔的...
    熒惑3_3閱讀 1,393評(píng)論 0 1
  • 夏日的早晨褪尝,悶熱的感覺(jué)隨著灰厭厭的太陽(yáng),一點(diǎn)點(diǎn)加碼!溫?zé)嶂械娜藗兿袂嗤芤粯悠谌鞓?lè)的適應(yīng)著河哑,女人們的裙子肥大而飄逸,...
    石頭流淚閱讀 229評(píng)論 0 2
  • 版權(quán)說(shuō)明:本文為 開開向前沖 原創(chuàng)文章龟虎,轉(zhuǎn)載請(qǐng)注明出處璃谨;注:限于作者水平有限,文中有不對(duì)的地方還請(qǐng)指教 前言:現(xiàn)在...
    開開向前沖閱讀 5,421評(píng)論 1 8
  • 你可以不漂亮,你可以不溫柔棉安,你可以不富有底扳,甚至你可以不友善,但你不可以沒(méi)有教養(yǎng)贡耽。 今天中午和朋友一起外...
    372a44c29777閱讀 341評(píng)論 2 3