前言(日常廢話)
本篇文章記錄了本人所知道的用原生JS來擷取到DOM元素節點的幾種辦法,做個記錄,加深記憶,友善以後複習。
正文
本文所做示範基于下面的HTML結構:

本文内容通過個人了解的分類進行歸納總結,大緻的目錄骨架如下:
目錄
- 一、通過document頂層方法擷取
- 1、document擷取html,head,body标簽
- 1.1、擷取html标簽
- 1.2、擷取head标簽
- 1.3、擷取body标簽
- 2、getElementBy系列擷取
- 2.1、通過ID擷取
- 2.2、通過類名擷取
- 2.3、name屬性擷取
- 2.4、通過标簽名擷取
- 3、query系列擷取
- 3.1、通過query選擇器擷取一個元素
- 3.2、通過query選擇器擷取一組元素
- 4、小結
- 1、document擷取html,head,body标簽
- 二、通過節點的屬性擷取
- 1、擷取父節點
- 1.1、parentNode擷取父節點
- 2、擷取子節點
- 2.1、childNodes擷取所有子節點
- 2.2、children擷取所有子節點
- 2.3、firstChild擷取首個子節點
- 2.4、lastChild擷取最後一個子節點
- 3、擷取兄弟節點
- 3.1、previousSibling擷取前一個兄弟元素
- 3.2、nextSibling擷取後一個兄弟元素
- 3.3、本節小結
- 4、小結
- 1、擷取父節點
一、通過document頂層方法擷取
我們要擷取DOM最先想到的代碼段就是document系列,通過控制台列印
console.log(document)
,可以看到document代表的是整個頁面文檔。
然後我們就可以通過各種類型的方法去擷取document下面的各個節點了,接下來進行逐一說明:
1、document擷取html,body标簽
本節前言:要擷取html,head,body标簽不是隻能用下面的辦法,隻是下面的三種方法是專門用來擷取它們的,是以單獨分類在這裡介紹,你也可以用後文介紹到的那些方法(通過選擇器擷取之類的)來擷取到這三個标簽。擔心大家被我這小節的标題誤導了,是以啰嗦一下,廢話不多說,開始本小節:
1.1、擷取html标簽
擷取html标簽有一個專門的方法,那就是
document.documentElement
,列印到控制台,如下圖所示:
1.2、擷取head标簽
擷取head标簽也有一個專用方法:
document.head
,列印到控制台,如下圖所示:
1.3、擷取body标簽
擷取body标簽同樣有一個專門的方法:
document.body
,列印到控制台,如下圖所示:
2、getElementBy系列擷取
在寫HTML頁面時,我們為了語義化,會用到各種各樣的标簽,有時也會給标簽設定上id、class、name等屬性,這些行為都為我們在js代碼中擷取這個DOM元素提供了便利,我們就可以通過document提供的getElementBy系列來進行元素節點的擷取:
2.1、通過ID擷取
通過ID擷取元素的方法是
document.getElementById('在想要擷取到的元素标簽上設定的id名')
通過列印
document.getElementById('father')
可以看到因為ID具有的唯一性,是以通過這個方法傳回來的是單獨一個元素:
如果你不小心給兩個标簽添加了一樣的id,那他在擷取到第一個id比對的标簽時便會停止搜尋,如下圖所示,我在原有的結構前面加了一個同樣是father ID的div
這個時候通過這個
getElementById(“father”)
列印出來的元素就是這個新加的,而不是我們剛剛列印的那個。
2.2、通過類名擷取
通過類名擷取元素的方法是
getElementsByClassName('在想要擷取到的元素标簽上設定的class類名')
通過列印
document.getElementsByClassName('box')
我們就可以在控制台看見在我們的頁面中設定的class為box的元素标簽了:
我們可以發現上面列印出來的和我們通過id列印出來的不太一樣,列印出來的是HTMLCollection(關于HTMLCollection這個概念,看官大老爺們可以自行百度,因為我對它的了解也不夠深)一個數組,數組裡面存放的就是我們要擷取的标簽了,為什麼是數組呢,因為我們知道在HTML中css的樣式class屬性是可以多個标簽共用的,是以我們擷取到的就是一個數組了(個人了解它設定成這樣是因為這個原因,如果有錯請指正,小白馬上修改,盡量不誤人子弟)。
知道了傳回來的是一個數組,那我們在取元素的時候就用數組取值的方法即可比如
document.getElementsByClassName('box')[0]
來擷取到class為box的标簽組裡的第一個标簽元素。
2.3、name屬性擷取
通過name屬性擷取元素的方法是
getElementsByName('在想要擷取到的元素标簽上設定的name屬性值')
通過在控制台列印
console.log(document.getElementsByName('fatherBox'))
就可以在控制台看見傳回的是一個NodeList(NodeList這個概念和前面通過class類名擷取裡面提到的HTMLCollection概念相似但是又有不同,因為本小白也說不明白,是以具體的還請看官大佬們自行百度)數組,
2.4、通過标簽名擷取
通過标簽名擷取元素的方法是
getElementsByTagName('想要擷取到的元素标簽名')
如果既沒有給元素設定id,name這樣的辨別符,也沒有添加class類,那要怎麼擷取到标簽元素呢,getElementsByTagName滿足你的要求。在控制台列印
document.getElementsByTagName('div')
可以看到傳回了一個HTMLCollection數組,數組裡面包含了我們HTML中的所有div
3、query系列擷取
當我們隻有父元素有設定id、class、name值,然後HTML内容又偏多時,這個時候用上面的那四種選擇器都不太友善,所有在HTML5中添加了query選擇器來幫助我們更友善的擷取到元素。
3.1、通過query選擇器擷取一個元素
通過query選擇器擷取一個元素的方法是
querySelector('根據css選擇器的規則選擇想要擷取到的元素')
,注意要根據css選擇器的比對規則去擷取。當選擇器選擇的内容為多個時,會隻選擇比對到的第一個元素傳回,但是這裡的第一個和前面ById選擇器的選擇第一個傳回不太一樣,比如你還是不小心給兩個元素寫了一樣的Id,都是father,然後第一個father裡面沒有div,第二個father裡面有多個div,這個時候querySelector會先比對到第一個father然後往裡面比對,發現沒有可以比對到的div來傳回,他就會進入到第二個father裡面進行比對,将比對到的第一個div進行傳回處理;但是,如果第一個father裡面有了可以傳回的div,那麼它就不會比對第二個father。可能說的不夠直覺,我們直接上圖:
(1)兩個father,第一個father裡面沒有div
在控制台列印
document.querySelector('#father>div')
(2)兩個father,第一個father裡面有div
在控制台列印
document.querySelector('#father>div')
3.2、通過query選擇器擷取一組元素
通過query選擇器擷取一組元素的方法是
querySelectorAll('根據css選擇器的規則選擇想要擷取到的元素')
,注意要根據css選擇器的比對規則去擷取。
在控制台列印
document.querySelectorAll('#father>div')
可以看到傳回了一個NodeList數組,裡面包含着我們通過比對規則比對到的所有div元素。
可能有看官大佬就好奇了,這時候要是多寫了個重複id的元素會出現啥情況呀,别急,我給您列印出來了,還是上面那個兩個father,第一個father裡面有一個div,第二個father裡面有三個div的結構,再列印一遍
document.querySelectorAll('#father>div')
:
我們可以看到他把兩個重複id的父級元素裡面的子div全都擷取進數組了。
4、小結
到這裡通過document頂層方法擷取元素标簽的方法就結束了,下面是通過節點的一些屬性來擷取元素的内容。其實到這裡我們已經可以擷取到任何在HTML中的DOM元素并對其進行一些需求的操作了,後面的内容可以當做一個補充進行相關的了解,也許有用到的時候也說不準嘛…
二、通過節點的屬性擷取
每個DOM元素其實都可以看作是一個對象,在這個DOM元素對象裡面有着用于擷取各類節點的屬性,我們可在通過第一節介紹的方法擷取到一個節點,然後通過操作這個節點上的屬性擷取到想要的元素節點。
1、擷取父節點
1.1、parentNode擷取父節點
我們可以通過parentNode屬性擷取到元素的父節點,比如在控制台列印
document.getElementsByClassName('box2')[0].parentNode
就可以擷取到類名為box2的元素數組中第一個元素的父節點了,列印結果為:
2、擷取子節點
2.1、childNodes擷取所有子節點
我們可以通過childNodes屬性擷取到元素的父節點,比如在控制台列印
document.getElementById('father').childNodes
就可以擷取到ID為father的元素底下的所有子節點了,通過觀察控制台我們可以看見傳回了一個NodeList數組:
我們可以看到數組裡面出現了一些奇怪的東西–
text
,這個其實是我們在編輯器裡面打代碼時為了代碼結構清晰一些,打的空格。每一個子元素的頭尾但凡有空格的地方都會解析成text并加入到數組裡面。我們要操作這樣的數組就很難受了,是以不推薦使用這個辦法。
2.2、children擷取所有子節點
我們還可以通過children來擷取所有的子節點,這個屬性和childNodes一樣都會傳回一個數組,隻不過傳回的是一個HTMLCollection數組。在控制台列印
document.getElementById('father').children
結果如下:
可以看到,我們擷取到的數組和用childNodes擷取到的子節點數組不太一樣,它沒有奇奇怪怪的東西–
text
,這種情況下,我們可以更好的進行需求操作,是以如果你要用節點的屬性來擷取全部子節點時,推薦使用children而不是childNodes。
2.3、firstChild擷取首個子節點
當我們要擷取一個元素的首個子節點時,我們就可以使用firstChild屬性啦。同樣的在控制台列印一下看看傳回結果
console.log(document.getElementById('father').firstChild)
:
我們發現列印出來了一個似曾相識的東西,前面childNodes傳回的數組裡面出現過的
text
,那這應該也是空格的問題吧,将第一個子節點前面的空格給删了再看看
可以看到他完美的傳回了我們想要的東西。
因為他不會過濾換行空格之類的是以可以将它變相的認為是
childNodes[0]
。
2.4、lastChild擷取最後一個子節點
當我們要擷取一個元素的最後一個子節點時,我們就可以使用lastChild屬性啦。同樣的在控制台列印一下看看傳回結果
console.log(document.getElementById('father').lastChild)
:
可以發現依舊是換行、空格的問題,和firstChild解決方法略有不同的是,firstChild去除的是第一個子節點前面的間隙,而lastChild要去除的是最後一個子節點後面的間隙:
這個時候再列印就會得到我們需要的最後一個子節點元素了:
3、擷取兄弟節點
使用sibling系列屬性來擷取兄弟元素
3.1、previousSibling擷取前一個兄弟元素
使用
previousSibling
擷取前一個兄弟元素,通過控制台列印
document.getElementsByClassName('box2')[0].previousSibling
來擷取box2前面的兄弟元素:
3.2、nextSibling擷取後一個兄弟元素
使用
nextSibling
擷取後一個兄弟元素,通過控制台列印
document.getElementsByClassName('box2')[0].nextSibling
來擷取box2後面的兄弟元素:
3.3、本節小結
注意擷取兄弟元素同樣會有換行、空格解析成
text
的問題,是以在使用時要把兄弟元素與本元素之間的間隙都删除掉,換句話說就是删除掉已經擷取到的節點前後的間隙:
4、小結
會列印出
text
的幾個方法(childNodes擷取所有子節點、firstChild擷取首個子節點、firstChild擷取首個子節點、lastChild擷取最後一個子節點、previousSibling擷取前一個兄弟元素、nextSibling擷取後一個兄弟元素),個人不建議使用,現在編輯器都是格式化美化代碼,一不留神就換行了,那真的就是到處都是
text
了。
寫給看貼的你
不知道還有什麼沒提到的擷取方式,希望看官大老爺們将上述未及的方法評論在下面,帶小白一把,共同進步,萬分感謝~
本人見識短淺,如有錯誤以及缺漏的地方請指正批評;如有涉及侵權,請手下留情,聯系本人,看見即删(手動狗頭保命)。
祝各位看官大佬們身體健康、諸事順心、仙運榮昌、少寫bug多加薪…