iT邦幫忙

2023 iThome 鐵人賽

DAY 26
1
Modern Web

GPT 救救我!菜雞小海獺的前端成長之旅系列 第 26

D26 - JS - 基礎 - DOM - 1 - 元素的操作

  • 分享至 

  • xImage
  •  

藉由前面的文章,知道了各種 HTML、CSS 與 JavaScript 的一些基本使用,接下來來了解怎麼透過 JavaScript 來影響網頁上的元素。

DOM 與 BOM 概述

BOM

瀏覽器物件模型(Browser Object Model,BOM),是瀏覽器提供的各種物件,JavaScript 可以透過使用這些物件來與瀏覽器互動。雖然 BOM 並沒有統一的標準,但現代瀏覽器都有下列這些物件可以操作:

  • window:最頂層;所有瀏覽器都支援,代表瀏覽器的視窗。
    • Screen:含有使用者的螢幕畫面資訊
    • Location:可取得當前頁面位址(URL)並導向新頁面
    • History:含有瀏覽器的歷史紀錄,可以控制上一頁及下一頁
    • Navigator:可存取使用者瀏覽器的資訊
    • Popup Alert:可使用瀏覽器內建的三種彈跳窗:alert、confirm、prompt
    • Timing:可使用 JavaScript 內建方法(setTimeout、setInterval)來使用瀏覽器內建的計時器
    • Cookies:可將網頁中的使用者資訊儲存在 cookie 中

DOM

當瀏覽器載入了一份 HTML 檔案,瀏覽器為當前的頁面建立了文件物件模型(Document Object Model, DOM)。此時,網頁上的每個部分都是 querySelector 的一個節點,可以透過瀏覽器提供的 API (Browser APIs),使用 JavaScript 來操控節點內的 HTML,CSS 或其行為。

以下介紹一些常用的控制 DOM 元素(elements)的方法。

querySelector() 與 querySelectorAll()

querySelector()

回傳與(一群)指定選擇器匹配的第一個元素節點。若找不到,回傳 null。
depth-first pre-order traversal:為了能更完整的搜尋,querySelector() 會由淺至深的走過每個節點,找到相符的第一個目標元素並回傳。

querySelectorAll()

回傳與指定選擇器相符的靜態(static )元素節點列表清單(Node List)。若找不到,回傳 null。

// 語法
// querySelector()
querySelector(selectors);

// querySelectorAll()
querySelectorAll(selectors)

參數說明:

  • selectors:要搜尋的一或多個選擇器字串,字串必須遵守 CSS 語法,否則會回傳 SYNTAX_ERR
  • 回傳值:
    • 若給予的選擇器群組無效,會回傳 SYNTAX_ERR

如何使用選擇器定位元素

querySelector 的 selectors 只接受「元素」,不支援偽類(例 div:hover)。也支援以選擇器列表(Selector list,,)來組合選擇器。

可以看這篇來了解 CSS 選擇器怎麼使用:D7 - CSS - 選擇器們 - 基本、分組與組合 - iT 邦幫忙

來個練習吧!例子來自 GPT

<div class="box">
  <p>嗨你好</p>
  <p>我是</p>
  <p>一隻</p>
  <p>海獺</p>
</div>
<ul>
  <li>項目 1</li>
  <li>項目 2</li>
  <li>項目 3</li>
</ul>
// 使用 querySelector() 選擇元素
const div = document.querySelector(".box");
console.log(div); // 會拿到符合 class=box 的第一個元素

// 使用 querySelectorAll() 選擇多個元素
const li = document.querySelectorAll("li");
console.log(li); // 會得到 li 的 node list

createElement()

可依 tagName 建立指定 HTML 元素。
若無法識別 tagName,則建立 HTMLUnknownElement。

// 語法
createElement(tagName)

參數說明:

  • tagName:字串,要建立的 HTML 元素。
  • 回傳值:一個新的元素

來個練習吧!例子來自 GPT

// 建立一個新元素
const newDiv = document.createElement('div');

appendChild()

將一個節點加到指定的父節點下的清單末端。

// 語法
appendChild(aChild)
Node.appendChild<HTMLDivElement>(aChild: HTMLDivElement): HTMLDivElement

參數說明:

  • aChild:指定的子節點
  • 回傳值:返回追加後的子節點

來個練習吧!例子來自 GPT,略加修改

<div class="list">
  <ul>
    <li>吃飯</li>
    <li>睡覺</li>
    <li>打東東</li>
	<!-- 會出現在這邊 -->
	<!-- <li>這是做出來的 li</li> -->
  </ul>
</div>
// 找到要掛的父元素
const list = document.querySelector(".list");
const ul = list.querySelector("ul");
// 建立一個新元素
const newLi = document.createElement('li');
// 設置元素的內容
newLi.textContent = '這是做出來的 li';
// 將元素掛到父元素的末端
ul.appendChild(newLi);

childNodes 與 parentNodes

共通點:

  • 都是唯讀屬性
  • 動態(節點清單)意即 DOM tree 發生變化時,節點(清單)也會隨著更新

childNodes

  • 會回傳指定節點之子節點的動態節點清單。
  • 動態節點清單內的第一個元素之索引值為 0
  • 這些節點都是物件,故若想從中取得資料,需要使用他們的屬性。例:elementNodeReference.childNodes[0].nodeName.
  • document 本身具有兩個子節點:Doctype declaration 和 root element(根元素,對 HTML 文件來說是 <html> 元素)
  • 回傳值:一份子節點的動態清單

parentNodes

  • 會回傳指定節點之父節點。
  • 回傳值:指定節點的父節點。父節點可以是元素、document 或 DocumentFragment。
    • null:沒有父節點的狀態下,有幾種可能
      • 當指定節點為 Document 或 DocumentFragment 時
      • 節點剛建立但尚未加入至 DOM tree 上時

以下是用法的例子與練習 from GPT

<div id="parent">
  <p>Paragraph 1</p>
  <p>Paragraph 2</p>
  <p>Paragraph 3</p>
</div>
// childNodes
const parent = document.getElementById("parent");
const childNodes = parent.childNodes;

for (let i = 0; i < childNodes.length; i++) {
  if (childNodes[i].nodeType === Node.ELEMENT_NODE) {
    console.log(childNodes[i].textContent);
  }
}

// 結果
// i=0, textContent = Paragraph 1
// i=1, textContent = Paragraph 2
// i=2, textContent = Paragraph 3

// parentNodes
const paragraph = document.querySelector("#parent p");
const parent = paragraph.parentNode;
console.log(parent.tagName); // div

參考資料

  • 重新認識 JavaScript: Day 11 前端工程師的主戰場:瀏覽器裡的 JavaScript,https://ithelp.ithome.com.tw/articles/10191666
  • BOM Browser Object Model 瀏覽器物件模型 - JavaScript (JS) 教學 Tutorial,https://www.fooish.com/javascript/bom-browser-object-model.html
  • 給開發者的網頁技術文件 | MDN,https://developer.mozilla.org/zh-TW/docs/Web
  • DOM 概述 - Web API 接口参考 | MDN,https://developer.mozilla.org/zh-CN/docs/Web/API/Document_Object_Model/Introduction
  • 文件物件模型 (DOM) - Web APIs | MDN,https://developer.mozilla.org/zh-TW/docs/Web/API/Document_Object_Model
  • Web APIs | MDN,https://developer.mozilla.org/zh-TW/docs/Web/API
  • DOM - 術語表 | MDN,https://developer.mozilla.org/zh-TW/docs/Glossary/DOM
  • JavaScript Window: BOM,https://www.w3schools.com/js/js_window.asp
  • DOM 海(?)列表:[文件物件模型 (DOM) - Web APIs | MDN,https://developer.mozilla.org/zh-TW/docs/Web/API/Document_Object_Model)
  • Document: querySelector() method - Web APIs | MDN,https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector
  • Document: querySelectorAll() method - Web APIs | MDN,https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll
  • 使用选择器定位 DOM 元素 - Web API 接口参考 | MDN,https://developer.mozilla.org/zh-CN/docs/Web/API/Document_object_model/Locating_DOM_elements_using_selectors
  • Document: createElement() method - Web APIs | MDN,https://developer.mozilla.org/en-US/docs/Web/API/Document/createElement
  • Node.parentNode - Web API 接口参考 | MDN,https://developer.mozilla.org/zh-CN/docs/Web/API/Node/parentNode
  • Node: childNodes property - Web APIs | MDN,https://developer.mozilla.org/en-US/docs/Web/API/Node/childNodes

上一篇
D25 - JS - 基礎 - 其他
下一篇
D27 - JS - 基礎 - DOM - 2 - 元素的新增與修改
系列文
GPT 救救我!菜雞小海獺的前端成長之旅30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言