---
# System prepended metadata

title: DOM 基礎操作 & classList
tags: [ALPHACampWeek3]

---

###### tags:`ALPHACampWeek3`

DOM 基礎操作 & classList
===

What is DOM
---
- 我們可以說 DOM 和 CSSOM 就是瀏覽器開放給 JavaScript 的 API。

- javascript的流程：CSS(CSSOM)&HTML(DOM)還沒形成render(渲染tree時javascript就介入操作。

DOM擷取的樣子
---
- 以 p 和 em 為例，在物件模型裡形成了父子階層關係
![](https://i.imgur.com/OwEkB00.png)

最常使用的DOM querySelector & querySelectorAll & document.getElementById
---
- document.querySelector
document.querySelector('.card-body ul')

- document.querySelectorAll('li') 
會回傳一個類似陣列的 NodeList：只能使用以下三點操作。
1. 查看長度 length
2. 遍歷內容 forEach
3. 使用 index 來存取特定項目

DOM最基本拿到標籤裡的內容方式
---
document.querySelector('.my-name').innerHTML  
- 可能遭遇XSS攻擊

document.querySelector('.my-name').innerText  
- 可能會有回流

document.querySelector('.my-name').textContent
- 可以避免回流

DOM操縱父子節點
---
document.querySelectorAll('.static-board tr')[1].children[0]

新增節點 document.createElement(tagName)
---
- 一般都會放進一個變數才能進一步修改
let h1 = document.createElement('h1')

抽換節點內容  NODE.innerHTML & NODE.innerText
---
- NODE.innerHTML = "htmlContent" - 會解析 HTML 標籤

- NODE.innerText = "textContent" - 不會解析 HTML 標籤（只處理文字）
h1.innerHTML = "This sentence is created by JavaScript"

將節點插入 DOM Tree appendChild、insertBefore | replaceChild
---

- 以下三種方法都可以插入節點
1. ul.insertBefore(li, ul.firstChild)
2. ul.appendChild(li)
3. ul.append(li)

- 元素建立之後，在瀏覽器上還看不到，需要透過 appendChild、insertBefore 或 replaceChild 等方法將新元素加入至指定的位置之後才會顯示。
![](https://i.imgur.com/M6xlUgc.png)

Modern style 簡化操縱DOM流程，IE不普及
---
![](https://i.imgur.com/etV4ofZ.png)

```javascript=
let list = document.querySelector('#list')

list.before('before')
list.after('after')

let prepend = document.createElement('li')
prepend.innerHTML = 'prepend'
list.prepend(prepend)

let append = document.createElement('li')
append.innerHTML = 'append'
list.append(append)
```
刪除節點 parentElement.removeChild(NODE) & NODE.remove()
---
1. parentElement.removeChild(NODE) 
2. NODE.remove()

操作 CSS 設置多重屬性
---
- NODE.classList - 查看目前所有 class 名稱，會回傳類似陣列的清單
- NODE.classList.add(className1, className2) - 加入一個或多個樣式
- NODE.classList.remove(className1, className2) - 刪除樣式
- NODE.className = className - 如果樣式只有一個，也可以直接寫入

- DOM 也有提供 style 屬性，例如：
NODE.style.backgroundColor
NODE.style.borderStyle

- 但還是建議先寫好CSS文件會比較清楚


className vs. classList.add
---
- element.className會覆蓋
element.className = "nav navbar" //怎麼好像不能用

- element.classList.add會append在後面
element.classList.add('nav', 'navbar')

- DOM 也有提供 style 屬性，例如：
NODE.style.backgroundColor
NODE.style.borderStyle
....

操作CSS-2 node.setAttribute設置單一屬性
---
```javascript=
em.setAttribute('class', 'red'); //對em標籤增加一個屬性class ='red'
```


完整新增/替換DOM步驟
---
```javascript=
const container = document.querySelector('.container')
const h1 = document.createElement('h1')
h1.innerHTML = 'This sentence is created by JavaScript'
container.appendChild(h1)
```


