JavaScript進階(二十一):父子節點,節點類型,document

這裏我們開始說一些有關於 DOM 節點相關的一些事。

節點這個東西很簡單,我們也叫它標籤,平常我們用的 div,span 這些東西,都是節點。

當然,在這過程當中,節點它其實有很多很多的關係,遠的我們不說,就說一近的。

比如,現在有一個 div,然後它裏面還有一個 span:

那麼這個 div,它就是 span 的父級。而 span,就是 div 的子級。

當然我們知道,一般情況下,父級只有一個,但是子級卻可以有一堆,比如:

 

然後一般來講,我們可以通過各種各樣的一些東西,來獲取它的父級或者子級。

其中,父節點是最容易用的,就直接叫做 parentNode

比如,現在來一個最簡單的,我給一個 span 加上 id,然後我們來獲取它,並且打印出它的 parentNode:

然後這個時候,你可以明確的看到,它的父級就是 div。

 

然後我們重點要說的其實是另外一個東西,就是除了父節點以外,我們還有子節點,而這個子節點,就稍微有一點麻煩了。

在我們的 js 裏面,有兩個方法來獲取子節點:

一個叫做 children,相信這個東西大家很常用。

還有一個略微有點坑人,叫做 childNodes

從意思上來說,其實差不多:children 翻譯過來就是孩子們,childNodes 翻譯過來就是孩子節點們。

那有什麼區別呢?我們來看看。

比方說,現在我把 div 它的 children 給拿出來:

你可以看到,它給我一個 HTMLCollection。

注意,所有通過這些獲取元素的方式,出來的東西,它都不是真正的數組,它是一個類數組。

然後你可以看到它裏面有 3 個 span。

 

然後接下來就是我們的 childNodes。

實際上來說,我們平常用 childNodes 用的少,但是有些情況下,你還就得用它,沒它就不行,怎麼回事呢?

我們先來看一下效果:

注意,實際上來說,你可以看到,它裏面除了 3 個 span 以外,還有一堆的 text,這是什麼意思?

所謂 text,其實是一種有點特殊的節點類型,叫做文本節點。

我們平常的這種 span,h1,div 這些東西,叫做 ElementNode 元素節點,而 textNode,它叫做文本節點。

那麼這時候,比方說,我在上面弄一行字:

那這個文本節點,一目瞭然。

你可以看到,就是它:

那麼反過來,我們可能會有點奇怪。

比如說,這 3 個 span 之間,它們怎麼還有文本呢?

其實這些文本都是你加的。

簡單來說,空格,對於我們人類來說,可能是個沒意義的字符。

但對於計算機來說,它就是一個字,空格也是字。

所以說,在這種情況下,你這裏的空格,它也會變成一個文本節點,叫做空文本節點。

 

當然,假設我把這幾個 span 之間的空格,給它徹底刪除。

那麼這時候你可以看到:

就只剩下 5 個了。

3 個 span 之間是不是就空了?

就這麼簡單,就是那幾個換行。

 

當然,這時候我們也就要說說了,爲什麼這個 childNodes 不太常用,其實原因就在這了。

因爲這個 childNodes,它不光包括元素節點,比如那幾個 span。

它也包括文本節點,就像上面,不管你是有字的,還是空的,它都包含。

 

但是,我們平常來講,幾乎不太會去直接操作文本節點,因爲它只是我們的內容,我們不太會操作它。

比方說,我們加個樣式,加個事件,都是對元素而言,文本節點你也加不上事件。

所以這就是爲什麼,平常它不太常用的原因。

 

所以,children 的特點,就是隻有元素節點,別的一律沒有。

childNodes,它是所有的節點,它都有。既包括元素節點,也包括文本節點,甚至於還包括註釋節點和其他的一些東西。

比如:

那麼這時候你可以看到,它裏面除了 text 以外,還多了一個 comment,也就是註釋節點。

這個註釋節點,對我們平常而言,幾乎是沒有任何實際意義的。

當然,以後我們會用到它的,因爲它的性能最高。

 

反正你就記住一件事,children 只有元素,而 childNodes 什麼都有。

正因爲 childNodes 什麼都有,所以比較亂,這就是爲什麼我們平常用它比較少的原因。

那麼現在,我們就瞭解了,子節點其實分成兩種。

 

接下來,我們還要說一個事情,就是,節點其實是有類型的。

就比如說,剛纔的 childNodes,因爲某種原因,我現在就需要用它,那麼這時候,我在循環的時候,是不是就得小心一點?我得看一看,到底是什麼東西,給我的是個元素,還是個文本,或者是註釋,還是個別的東西。

所以,每一個節點,只要是 HTML 裏面的節點,它都有一個類型。

每個節點身上都有一個東西,叫做 nodeType。

那麼我們來實驗一下,比如 div 下面的第一項是什麼?

可以看到,它就是一個文本,一些字。

然後,我們主要想看看它的類型是什麼:

那麼這個時候你可以看到,它給我們一個 3。

 

實際上來說,節點類型這個東西,是以數字的形式來存在的。

當然有人會說,記不住啊,這誰能記得住?

其實這個倒不用你去記,因爲首先,常用的就 2、3 個。其次,我們的 document 上,其實有它原始類型的定義。

比方說:

注意,它是全大寫的,因爲它是一個常量。

那麼這時候你可以看到,是一個 true,說明它是一個文本節點。

 

當然除了這些以外,還有很多別的一些節點。

比方說,現在我們要第一個 div.childNodes[1],也就是 span:

現在這時候你可以看到,它就是一個 span,並且是一個 1。

當然這個 1,它也有自己相應的一個類型定義,document 上有一個東西叫做 ELEMENT_NODE,元素節點。

你可以看到,是 true。

 

所以這時候,我們就看到了:

nodeType,首先它是一個數字。

其次,這個數字有一些比較常用的:

我們比較常用的 1,它對應的是 document.ELEMENT_NODE,元素節點。

然後還有一個 3,這個對應的是 document.TEXT_NODE,文本節點。

 

然後現在我們就來看看第五個節點,註釋節點:

這時候,你可以看到,它是一個 8,它對應的就是 document.COMMENT_NODE,註釋節點。

所以這時候,我們就又看到了一個東西。

 

當然,這個 nodeType 的類型其實是挺全的,它裏面不光包括這種我們平常能夠用的着的類型,甚至於還包括一些比較怪異的類型,或者說不太常用的一些類型。

比方說,在我們整個的 DOM 操作的過程當中,其實有一個節點是最特殊的,這個節點叫做 document。

document 它其實也是一個虛擬的 HTML 節點,我們先把它打印出來看看:

 

這個 document,我們需要稍微來認識它一下,我們老用到 document,那它到底是什麼?到底什麼叫 document?

首先是這樣的,我們先來看一個特別有意思的現象。

document 上有一個很特殊的東西叫做:document.documentElement

當然,平常我們都是用的 document.body:

document.body 我們都用過,這就是 body,沒啥可說的。

那麼,這個 document.documentElement 它是什麼呢?

其實它就是 html。

你可以看到,其實 document.documentElement,它就是 html 的簡稱。

當然,它是沒有 document.html 的:

這個是空的,沒有的。

 

那麼現在,我就想看一個最簡單的東西,document.documentElement.parentNode 是誰?

換句話說,我們平常從來沒有探究過 html 的父級是誰。

我明確的告訴大家,html 的父級,你一天到晚都在用,就是 document

換句話說,其實你可以這麼理解:

就是說,document,你可以認爲是一個看不見的頂級元素,我們所有的這些 HTML 的東西,全都在 document 裏面。

當然,這只是爲了便於大家去理解,實際上來說,這個 document,你是不能寫出來的,也沒人這麼寫。

所以我們知道了:document 是 html 元素的父級。

 

然後這個 document,其實它是一個接口,它本身其實並不是一個真的節點,因爲不用我們寫。

然後它裏面保存了各種各樣的方法,可以幫助你來調用 HTML 裏面的各種東西,比方說 getElementById,你沒有這些方法,你根本就操作不了 DOM。

 

既然我們說 document 它也是一個特殊的節點,那麼是節點,它就有 nodeType,那麼這時候我們可以來看一下:

你可以看到,它也是給我們一個數字的值 9。

9 這個值,它對應的類型就是 document.DOCUMENT_NODE:

實際上來說,在我們整個 HTML 裏面,就它一個人是 9 這個類型,沒有第二個。

當然,這個我們瞭解一下就行,平常也用不到這個。

 

那麼這時候,你可能會奇怪,你怎麼 1,3,8,9 跳着來? 2,4,5,6 之類的去哪了?

實際上來說,像 2,4,5,6 之類的,它並不是那麼常用的一些類型。

比如像 2,平常大家幾乎碰不到,它是一種 ATTRIBUTE_NODE 類型,就是一個所謂的屬性節點。

 

當然,這個東西在我們的 HTML 裏面,幾乎不太會用到。這時候大家可能會奇怪,不太用到,那爲啥會有它?

沒什麼,因爲 HTML 是 XML 的一個子級。

實際上來說,XML 裏面是有 ATTRIBUTE_NODE 的,所以它就繼承過來了。

所以除了 1,3,8,這三個以外,其他的類型,我們一般也用不着。

 

那麼接下來有一個問題,document 有父級嗎?

首先你得規定一下,怎麼就叫父級。按照我們一般的約定,我們認爲 parentNode 就是父級:

那麼你可以明確的看到,就是 null。

不好意思,document 我就是頭,我沒有父級。

當然,從對象本身的所屬關係上,它是屬於 window 的:

因爲,全局的東西,我們說都屬於 window。

document 也是一個全局的東西,所以它當然屬於 window。

所以我們就知道了,document 是沒有節點上的父級。

 

那麼到這爲止,我們就已經大概的理解了這個東西,稍微的來總結一下:

首先,我們說了一個很重要的東西,就是說這個節點,它之間是有關聯的,比如父節點,子節點。

父節點就一個,parentNode,沒了。

而子節點有兩個,children 和 childNodes:

children,它只有元素節點,我們平常一般都用它。

childNodes,它就是所有節點的一個大集合。

 

然後我們在處理節點的時候,往往需要知道這個節點到底是什麼類型的,我好對症下藥。

那麼這時候你就需要用到 nodeType 這樣的一個屬性。

這個是所有節點都有的一個屬性,並且它就是一個數字,當然也對應了一些值:

1  document.ELEMENT_NODE

3  document.TEXT_NODE

8  document.COMMENT_NODE

9  document.DOCUMENT_NODE

 

然後 document,它實際上來說,其實是一個虛擬的父級,整個 html 的頂點。

那麼現在,我們就對這個 DOM 的節點,有了一個大概的理解了。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章