基本概念
在講解操作DOM的api之前翔怎,首先我們來復(fù)習(xí)一下一些基本概念窃诉,這些概念是掌握api的關(guān)鍵,必須理解它們赤套。
Node類型
DOM1級定義了一個Node接口飘痛,該接口由DOM中所有節(jié)點(diǎn)類型實(shí)現(xiàn)。這個Node接口在JS中是作為Node類型實(shí)現(xiàn)的容握。在IE9以下版本無法訪問到這個類型宣脉,JS中所有節(jié)點(diǎn)都繼承自Node類型,都共享著相同的基本屬性和方法唯沮。
Node有一個屬性nodeType表示Node的類型脖旱,它是一個整數(shù),其數(shù)值分別表示相應(yīng)的Node類型介蛉,常見的如下:
常量 | 值 | 描述 |
---|---|---|
Node.ELEMENT_NODE |
1 |
一個 元素 節(jié)點(diǎn)萌庆,例如 <p> 和 <div> 。 |
Node.TEXT_NODE |
3 |
Element 或者 Attr 中實(shí)際的 文字
|
Node.PROCESSING_INSTRUCTION_NODE |
7 |
一個用于XML文檔的 ProcessingInstruction 币旧,例如 <?xml-stylesheet ... ?> 聲明践险。 |
Node.COMMENT_NODE |
8 |
一個 Comment 節(jié)點(diǎn)。 |
Node.DOCUMENT_NODE |
9 |
一個 Document 節(jié)點(diǎn)吹菱。 |
假設(shè)我們要判斷一個Node是不是元素巍虫,我們可以這樣判斷
if(someNode.nodeType == 1){
console.log("Node is a element");
}
這些Node類型中,我們最常用的就是element鳍刷,text占遥,attribute,comment输瓜,document瓦胎,document_fragment這幾種類型芬萍。
需要注意的就是:HTML中的節(jié)點(diǎn)并不只是包括元素節(jié)點(diǎn),它還包括文本節(jié)點(diǎn)搔啊,注釋節(jié)點(diǎn)等等
創(chuàng)建節(jié)點(diǎn)的常用api
- createElement
createElement通過傳入指定的一個標(biāo)簽名來創(chuàng)建一個元素柬祠,如果傳入的標(biāo)簽名是一個未知的,則會創(chuàng)建一個自定義的標(biāo)簽负芋,注意:IE8以下瀏覽器不支持自定義標(biāo)簽漫蛔。
使用如下:
var div = document.createElement("div");
使用createElement要注意:通過createElement創(chuàng)建的元素并不屬于html文檔,它只是創(chuàng)建出來旧蛾,并未添加到html文檔中莽龟,要調(diào)用appendChild或insertBefore等方法將其添加到HTML文檔樹中。
頁面修改型常用API
- appendChild
appendChild我們在前面已經(jīng)提到蚜点,就是將指定的節(jié)點(diǎn)添加到調(diào)用該方法的節(jié)點(diǎn)的子元素的末尾轧房。調(diào)用方法如下:
parent.appendChild(child);
child節(jié)點(diǎn)將會作為parent節(jié)點(diǎn)的最后一個子節(jié)點(diǎn)。
appendChild這個方法很簡單绍绘,但是還有有一點(diǎn)需要注意:如果被添加的節(jié)點(diǎn)是一個頁面中存在的節(jié)點(diǎn)奶镶,則執(zhí)行后這個節(jié)點(diǎn)將會添加到指定位置,其原本所在的位置將移除該節(jié)點(diǎn)陪拘,也就是說不會同時存在兩個該節(jié)點(diǎn)在頁面上厂镇,相當(dāng)于把這個節(jié)點(diǎn)移動到另一個地方。
需要注意的是:如果child綁定了事件左刽,被移動時捺信,它依然綁定著該事件。
- removeChild
removeChild顧名思義欠痴,就是刪除指定的子節(jié)點(diǎn)并返回迄靠,用法如下:
var deletedChild = parent.removeChild(node);
deletedChild指向被刪除節(jié)點(diǎn)的引用,它等于node喇辽,被刪除的節(jié)點(diǎn)仍然存在于內(nèi)存中掌挚,可以對其進(jìn)行下一步操作。
注意:如果被刪除的節(jié)點(diǎn)不是其子節(jié)點(diǎn)菩咨,則程序?qū)?bào)錯吠式。我們可以通過下面的方式來確保可以刪除:
if(node.parentNode){
node.parentNode.removeChild(node);
}
通過節(jié)點(diǎn)自己獲取節(jié)點(diǎn)的父節(jié)點(diǎn)抽米,然后將自身刪除特占。
- replaceChild
replaceChild用于使用一個節(jié)點(diǎn)替換另一個節(jié)點(diǎn),用法如下
parent.replaceChild(newChild,oldChild);
newChild是替換的節(jié)點(diǎn)云茸,可以是新的節(jié)點(diǎn)是目,也可以是頁面上的節(jié)點(diǎn),如果是頁面上的節(jié)點(diǎn)标捺,則其將被轉(zhuǎn)移到新的位置懊纳,oldChild是被替換的節(jié)點(diǎn)网持。
頁面修改型api要注意幾個特點(diǎn):
(1)不管是新增還是替換節(jié)點(diǎn),如果新增或替換的節(jié)點(diǎn)是原本存在頁面上的长踊,則其原來位置的節(jié)點(diǎn)將被移除,也就是說同一個節(jié)點(diǎn)不能存在于頁面的多個位置
(2)節(jié)點(diǎn)本身綁定的事件會不會消失萍倡,會一直保留著身弊。
節(jié)點(diǎn)查詢型API
節(jié)點(diǎn)查詢型API也是非常常用的api,下面我們分別說明一下每一個api的使用列敲。
document.getElementById
這個接口很簡單阱佛,根據(jù)元素id返回元素,返回值是Element類型戴而,如果不存在該元素凑术,則返回null。
使用這個接口有幾點(diǎn)要注意:
(1)元素的Id是大小寫敏感的所意,一定要寫對元素的id
(2)HTML文檔中可能存在多個id相同的元素淮逊,則返回第一個元素document.getElementsByTagName
這個接口根據(jù)元素標(biāo)簽名獲取元素,返回一個即時的HTMLCollection類型document.getElementsByClassName
這個API是根據(jù)元素的class返回一個即時的HTMLCollection扶踊,用法如下
var elements = document.getElementsByClassName(names);
這個接口有下面幾點(diǎn)要注意:
(1)返回結(jié)果是一個即時的HTMLCollection泄鹏,會隨時根據(jù)文檔結(jié)構(gòu)變化
(2)IE9以下瀏覽器不支持
(3)如果要獲取2個以上classname,可傳入多個classname秧耗,每個用空格相隔备籽,例如
var elements = document.getElementsByClassName("test1 test2");
- document.querySelector和document.querySelectorAll
這兩個api很相似,通過css選擇器來查找元素分井,注意選擇器要符合CSS選擇器的規(guī)則车猬。
(1)document.querySelector返回第一個匹配的元素,如果沒有匹配的元素尺锚,則返回null珠闰。
(2)document.querySelectorAll的不同之處在于它返回的是所有匹配的元素,而且可以匹配多個選擇符
兼容性問題:querySelector和querySelectorAll在ie8以下的瀏覽器不支持缩麸。
節(jié)點(diǎn)關(guān)系型api
在html文檔中的每個節(jié)點(diǎn)之間的關(guān)系都可以看成是家譜關(guān)系铸磅,包含父子關(guān)系,兄弟關(guān)系等等杭朱,下面我們依次來看看每一種關(guān)系阅仔。
- 父關(guān)系型api
- parentNode:每個節(jié)點(diǎn)都有一個parentNode屬性,它表示元素的父節(jié)點(diǎn)弧械。Element的父節(jié)點(diǎn)可能是Element八酒,Document或DocumentFragment。
- parentElement:返回元素的父元素節(jié)點(diǎn)刃唐,與parentNode的區(qū)別在于羞迷,其父節(jié)點(diǎn)必須是一個Element界轩,如果不是,則返回null
- 兄弟關(guān)系型api
previousSibling:節(jié)點(diǎn)的前一個節(jié)點(diǎn)衔瓮,如果該節(jié)點(diǎn)是第一個節(jié)點(diǎn)浊猾,則為null。注意有可能拿到的節(jié)點(diǎn)是文本節(jié)點(diǎn)或注釋節(jié)點(diǎn)热鞍,與預(yù)期的不符葫慎,要進(jìn)行處理一下。
previousElementSibling:返回前一個元素節(jié)點(diǎn)薇宠,前一個節(jié)點(diǎn)必須是Element偷办,注意IE9以下瀏覽器不支持。
nextSibling:節(jié)點(diǎn)的后一個節(jié)點(diǎn)澄港,如果該節(jié)點(diǎn)是最后一個節(jié)點(diǎn)椒涯,則為null。注意有可能拿到的節(jié)點(diǎn)是文本節(jié)點(diǎn)回梧,與預(yù)期的不符废岂,要進(jìn)行處理一下。
nextElementSibling:返回后一個元素節(jié)點(diǎn)漂辐,后一個節(jié)點(diǎn)必須是Element泪喊,注意IE9以下瀏覽器不支持。
- 子關(guān)系型api
- childNodes:返回一個即時的NodeList髓涯,表示元素的子節(jié)點(diǎn)列表袒啼,子節(jié)點(diǎn)可能會包含文本節(jié)點(diǎn),注釋節(jié)點(diǎn)等纬纪。
- children:一個即時的HTMLCollection蚓再,子節(jié)點(diǎn)都是Element,IE9以下瀏覽器不支持包各。
- firstNode:第一個子節(jié)點(diǎn)
- lastNode:最后一個子節(jié)點(diǎn)
- hasChildNodes方法:可以用來判斷是否包含子節(jié)點(diǎn)摘仅。
元素屬性型api
- setAttribute
根據(jù)名稱和值修改元素的特性,用法如下问畅。
element.setAttribute(name, value);
其中name是特性名娃属,value是特性值。如果元素不包含該特性护姆,則會創(chuàng)建該特性并賦值矾端。
如果元素本身包含指定的特性名為屬性,則可以訪問屬性進(jìn)行賦值卵皂,比如下面兩條代碼是等價(jià)的:
element.setAttribute("id","test");
element.id = "test";
- getAttribute
返回指定的特性名相應(yīng)的特性值秩铆,如果不存在,則返回null或空字符串。用法如下:
var value = element.getAttribute("id");
總結(jié)
本文主要總結(jié)了原生js中常用的操作DOM的api接口殴玛,主要為了復(fù)習(xí)基礎(chǔ)知識捅膘。平時開發(fā)用多了jQuery等類庫,對基礎(chǔ)知識的了解可能就漸漸地遺忘滚粟,但這些基礎(chǔ)知識才是我們立足的根本寻仗,只有掌握原生的js,才能真正做好js的開發(fā)凡壤。
參考資料:
1.Javascript操作DOM常用API總結(jié)
2.MDN文檔