0%

DOM - 操控 DOM 介面的方法

MDN的 Document Object Model (DOM) 介紹了許多 DOM 的相關資訊,有機會用到的話,再來仔細研究一下介紹之外的其他方法,這裡只會介紹最常用的部份。
之前曾寫過一篇DOM - 操控網頁元素的必學技巧這篇就算是再一次複習吧!

DOM 到底是什麼?

在學習如何操控 DOM 之前,先來好好的理解什麼是 DOM :

DOM 是文件物件模型(Document, Object, Model)與就是用來呈現與操控 HTML 的程式介面,或 XML 檔案的互動 API。也就是把 HTML 標記(Document)轉換成物件(Object)。
這個文件物件模型提供了一個文件(樹狀)的結構表示法,並且定義讓程式可以存取或修改文件的架構、風格與內容的方法。

DOM 提供了如樹狀結構的節點,這些樹狀結構的節點都可以有自己的屬性,在節點上也可以綁定事件處理的程序,一旦這些節點因使用者行為被觸發,就會執行綁定的程序。
簡單的說 DOM 就是 JS 跟 HTML 溝通的橋樑(牽紅線)。DOM 允許我們透過 JS 來操作 HTML(Document) 這個物件,但不能直接操控頁面上的標籤,DOM 所做的事就是瀏覽器幫 Object 轉換成 HTML 對應的標記,進而讓 JS 可以改變頁面上的元素。

什麼是 Window Object

在 JS 當中的 window Object,是指我們目前程式正在運行的電腦螢幕視窗(瀏覽器視窗)。這個 window 物件裡有許多方法,例如window.alert()或是window.addEventListener()透過這些 Window 物件裡的方法,來操控物件裡的元素。以下列舉幾個常用的方法,因 JS 本身會是寫在 Window Object 這個物件裡,所以寫 JS 時 window 可省略:

使用 JavaScript 來操控網頁元素(DOM)有三種方法:

  • 介面:如何改變介面
  • 事件:如何監聽事件並做出反應
  • 資料:如何與伺服器交換資料

選取 DOM 元素

  • Tag
  • Class Name
  • ID (getElementById) Element 為單數,因為 ID 只有一個。
  • CSS 選擇器
  • element.closest() 最靠近父層的元素
1
2
3
4
5
const header = document.getElementsByTagName('header'); // tag 指 HTML 標籤
const box = document.getElementsByClassName('box'); // class name
const icebox = document.getElementById('ice-box'); // ID
const icebox_p = document.querySelector('#ice-box p'); // 匹配到的第一個 #ice-box p
const icebox_p_all = document.querySelectorAll('#ice-box p'); // // 匹配到的 所有 #ice-box p ,抓取成為 NodeList Array

CSS 選擇器

  • CSS 選擇器最常使用querySelectorquerySelectorAll
  • querySelector只會抓取並回傳第一個找到的元素,
  • querySelectorAll 會選取匹配條件的元素,並且把收集到的元素存成陣列(NodeList)回傳回來。

改變 CSS

我們可以直接改變 DOM 的樣式,但是累贅,需要一個一個寫入 style 的屬性,最常處理的方式是在元素上加上 class 類別,需要時例如事件觸發時,再加上狀態或屬性。

1
2
const linkA = document.querySelector('.box a');
linkA.classList.add('active');

增加或刪減 className

  • 增加:.classList.add('active');
  • 移除:.classList.remove('active');
  • 切換:.classList.toggle('active'); 如果沒這個 class 就新增,有就移除
  • 包含:是否包含此 class.classList.contains('active'); 回傳布林值

取得、改變文字或標籤內容

會替代掉原本的元素內文字或內容

  • [DOM].innerText =
    只抓取元素的內容,不包含子元素,只能寫入存文字
  • element.innerHTML =
    會抓取元素的內容,包含子元素,且寫入標籤元素
    ex.element.innerHTML = '<div>Hello<div>'
  • element.outerHTML=
    不只改變元件內容,也可替換掉元件本身的標籤
    ex.element.outerHTML = '<div>Hello<div>'

加入與移除元素

  • Element.append()
    是在元素的最後一個子節點之後插入一組 Node 物件或是 DOMString 物件,被插入的 DOMString 物件等價為 Text 節點。

  • Element.appendChild(aChild)
    將一個節點加到指定的父節點,子節點的列表的末端。如果某個結點已經擁有父節點,使用此方法後,此節點會先被移除,在被插入到新的位置。如果要保留原本的節點,可先使用Node.cloneNode()來複製一份,再將這個複製的節點附加到目標父節點下。而使用Node.cloneNode()複製的節點不會自動保持同步。

  • Node.removeChild()
    從 DOM 移除一個子節點,並回傳移除的節點。

1
2
3
// 創建一個新的段落元素 <p>,然後增加到 <body> 的最尾端
const p = document.createElement('p');
document.body.appendChild(p);

複製元素

  • Node.cloneNode(Deep)
    參數如果是 tree,表示為深度 clone, 節點的所有的後代節點都會被複製,如果是 false 則只會複製節點本身。
    如是 深度 clone,需注意後代節點中是否有唯一的 ID
1
2
const p = document.getElementById('para1');
const p_prime = p.cloneNode(true);

學習程式就是如此,常常沒用的東西就忘了,要用的時會再來找其實也可以,但是如果可以使用的更熟練,應該可以省下一些時間找資料吧。