---
# System prepended metadata

title: 【Day23】懂得DOM就能控制網頁
tags: [JavaScript, 14th鐵人賽]

---

# 【Day23】懂得DOM就能控制網頁
###### tags: `JavaScript` `14th鐵人賽`
上一篇的介紹了解到JavaScipt是如何透過BOM及DOM來控制瀏覽器行為及網頁的內容，當新開的一網頁時，瀏覽器會去分析HTML的檔案並解析成DOM，而DOM也是網頁的根本，因此懂得控制DOM，就能夠控制整個網頁!

本篇介紹：

- 環境設置：`<script>`標籤要放在哪?
- DOM節點選取
- DOM節點類型
- 節點的父子關係

---

![https://ithelp.ithome.com.tw/upload/images/20220927/20151124uMkLRSxhnB.png](https://ithelp.ithome.com.tw/upload/images/20220927/20151124uMkLRSxhnB.png)

由於DOM的根部為document的原因，因此若在網頁console中直接輸入document就能呼叫到整個網頁，當游標移到document時整個頁面會被反選，展開內容就會看到head、body及各個節點。

![https://ithelp.ithome.com.tw/upload/images/20220927/20151124igEPeKClkI.png](https://ithelp.ithome.com.tw/upload/images/20220927/20151124igEPeKClkI.png)

## 環境設置：`<script>`標籤要放在哪?

![https://ithelp.ithome.com.tw/upload/images/20220927/20151124ga9rDYOlUL.png](https://ithelp.ithome.com.tw/upload/images/20220927/20151124ga9rDYOlUL.png)

上圖可以看到`<script>`是放在`<body>`的位置，可以將這一串移至`<head>`中，你會發現它仍然可以執行，那放置在這兩個地方右有什麼差別呢？

放置於`<body>`：在HTML分析檔案時是由上而下解析完成後變成DOM的節點`script`才有辦法讀取到內容

放置於`<head>`：由於沒解析到`<h1>哈哈哈</h1>`未產生節點，就要求讀取，因此頁面也會毫無反應

## DOM節點選取

DOM的節點類型包含HTML元素節點(element nodes)、文字節點(text nodes)、註解節點(comment nodes)……等。

我們可以透過`.querySelector( )`填入不同的CSS選擇器並抓到網頁中的元素。

```jsx
const element = document.querySelector('h1');
// ('')填入CSS選擇器，將選取第一個符合條件的元素，
const element = document.querySelectorAll('A');
// 選取所有符合條件的元素
```

其餘常見的選取節點的方式：

```jsx
document.getElementsById('A'); // 選取id為A的元素
document.getElementsByTagName('A') // 針對tag名稱回傳所有符合條件的集合
document.getElementsByClassName('A') // 針對class名稱回傳所有符合條件的集合
```

## DOM節點類型

不同的類型對應不同的常數值，可用於區分不同類型的節點，分別有12種類型對應1到12的常數值，以下舉出幾種常見的類型：

| 常數名稱 | 值 | 說明 |
| --- | --- | --- |
| Node.ELEMENT_NODE | 1 | 表示 HTML 元素 (Element) 節點ex: `<p>` 或 `<div>` |
| Node.ATTRIBUTE_NODE | 2 | 屬性節點 |
| Node.TEXT_NODE | 3 | 實際文字節點 ex:表示文字 (Text) 或屬性 (Attr) 節點 |
| Node.COMMENT_NODE | 8 | 表示註解節點 (Comment) |
| Node.DOCUMENT_NODE | 9 | 表示根節點 (Document) |
| Node.DOCUMENT_TYPE_NODE | 10 | 表示 DocumentType 節點 ex: `<!DOCTYPE html>` |
| Node.DOCUMENT_FRAGMENT_NODE | 11 | 表示 DocumentFragment 節點 |

其餘可參考[MDN Node.nodeType](https://developer.mozilla.org/zh-TW/docs/Web/API/Node/nodeType)

## 節點的父子關係

節點與節點間的關係，有以下兩種：

- 父子關係:除了`document`之外，每一個節點都會有個上層的節點，稱為父節點(Parent node)，而父節點的下層，稱為子節點(Child node)。
- 兄弟關係:有同一個父節點的關係，他們彼此就是兄弟節點(Siblings node)。

節點之間的查找關係：

`Node.childNodes` 獲取當前元素節點的所有子節點

`Node.firstChild` 獲取Node節點的第一個子節點

`Node.lastChild` 獲取Node節點的最後一個子節點

`Node.ownerDocument` 獲取Node的文檔根節點(document)

`Node.parentNode` 獲取Node節點的父節點

`Node.previousSibling` 獲取Node節點的「前一個」同級節點

`Node.nextSibling` 獲取當Node節點的「下一個」同級節點

範例說明：

```html
<p>
  <span>span 1</span><span>span 2</span><span>span 3</span>
</p>
```

```jsx
  var p = document.querySelector('p'); // 選取第一個p屬性
 
  console.log(p.lastChild.textContent); // 獲取p節點的最後一個子節點
 // textContent 屬性取得節點內的文字
```

子節點包含空白節點，因此若`<p>`與`<span>`間有換行將會取得空白節點

以上為本次DOM的介紹，大致了解DOM後下一篇將會說明如何使用DOM取值