Day 13: 原理篇 —— DOM 樹大探險:如何精準抓取網頁裡的元素?
當我們使用 HTML 構建出豐富的網頁結構後,若要透過 JavaScript 為其注入靈魂與互動能力,第一步就是學會如何與 DOM(文件物件模型,Document Object Model)溝通。本章節將帶領冒險者走進這座由標籤所構成的倒置「DOM 樹」,深入剖析 querySelector 與 querySelectorAll 的單點偵錯與全場掃描機制。我們將對照 ID、Class 與屬性選擇器的應用場景,探討類陣列 NodeList 的巡邏方式,並介紹如何運用 data-* 屬性與 dataset 實現資料與視圖的優雅分離,為後續的事件監聽與畫面渲染打下堅實基礎。
本文同步分享於2026鐵人賽:JS 核心重構:勇者轉職傳說
孩子,在踏上今日的領地前,先坐下來喝杯酒吧。 修煉的路很長,別急著奔跑,先聽聽這份卷軸裡的古老叮嚀。
我在每一站的盡頭都為你鋪設了 「
實戰演武場 CodePen」。那不只是程式碼的拼湊,而是你在這場暴風雨中,試圖用邏輯點燃的一顆星火。 成功突圍後,別忘了帶著你的戰利品回到 「QuestBoard 佈告欄」。在那裡,你會發現自己從不孤單,公會的夥伴們都正舉杯等待你的歸來。記住...
「 導師看重的從來不是你的劍法有多華麗,而是當你被邏輯擊潰、滿身泥濘後,依然選擇握緊理性的劍柄,再次向真相發起衝鋒的勇氣。 」
🛡️ 【公會大廳:導師的修煉導讀】
「導師,我已經蓋好這座城市(HTML)了,但我該怎麼抓到躲在城堡三樓的那個小怪物,叫他改名成『勇者之王』?」
我指著遠方說:「冒險者,身為專業的尋寶人,你必須學會『座標精準定位』。這不是胡亂射箭,而是順著這棵名叫 DOM (Document Object Model) 的大樹,找到地圖上唯一的標記。如果你抓錯了人,你的咒語就會噴發出 null 的霧氣,讓你當場卡死在副本門口。」今天,我們要學會如何在萬千元素中,一眼釘住你的目標。
💡 【導師講義:底層真相探究】
1. HTML 樹狀結構地圖 (The DOM Tree)
網頁裡的所有標籤(<div>, <p>, <h1>),在 JavaScript 的眼中其實都長得像一棵倒過來的「樹」。根部是 document,每條分枝都是一層巢狀關係。
🛠️ 定位術:QuerySelector 兩大傳送門
document.querySelector():單點偵錯儀- 行為:從起點向下掃描,一旦發現「第一個」符合條件的目標,就立刻停止並回傳。
- 回傳值:一個活生生的 Element 物件(沒找到則回傳
null)。
document.querySelectorAll():全場掃描儀- 行為:掃描整棵樹,把所有符合條件的人通通抓起來。
- 回傳值:一個 NodeList(類陣列清單)。你必須用
forEach巡邏一遍,才能對裡面的成員逐一下令。
2. 定位基準對照表
| 選擇器類型 | 範例語法 | 導師建議 |
|---|---|---|
ID (#) | querySelector('#login') | 最快、唯一。用於核心標靶(如登入鈕)。 |
Class (.) | querySelectorAll('.card') | 最常用。用於批量樣式的群組。 |
屬性 ([]) | querySelector('[data-id]') | 進階招式。處理複雜資料關聯時非常好用。 |
3. 邏輯流向圖解
DOM 樹就像是一座 「地下城的每一層地圖」。querySelector 就是你的精準掃描儀。你可以從最上面的 #castle 一層層往下掃描,直到你鎖定那個帶著寶貝的 .monster。

⚔️ 【戰術對抗:學長與學弟的代碼對決】
招式示範:精準定位術
❌ 冒險學弟:使用舊型號羅盤 (getElementById)
- 負能量評級:🔴 語法冗長 / 🔴 彈性極低
const name = document.getElementById("nickname");
// 囉嗦、難記,且無法使用複雜的 CSS 複合選擇器
✅ 勇者學長:全能的高效定位 (querySelector)
- 利潤評級:🟢 統一語法 / 🟢 支援 CSS 複雜選取
// 1. 抓取唯一目標 (ID 用 #)
const heroName = document.querySelector("#nickname");
heroName.textContent = "辛梅爾";
// 2. 抓取一群目標 (Class 用 .) 並批量處理
const monsters = document.querySelectorAll(".monster");
monsters.forEach((m) => m.classList.add("is-hidden"));
🏰 【勇者精英課:邁向職人的進階架構】
.dataset:標籤隱藏的公事包
抓到了元素,我們還需要能讀取它身上的隱藏資訊。
職人們最推薦使用 data-* 自訂屬性來儲存與 HTML 標籤關聯的業務資料(例如資料庫 ID)。
<div class="npc" data-id="99" data-job="mentor"></div>
const npc = document.querySelector(".npc");
console.log(npc.dataset.id); // "99"
console.log(npc.dataset.job); // "mentor"
這比直接把 ID 寫在 Class 或標籤內文裡乾淨得多,也更符合現代前端「資料與樣式分離」的架構思維。
孩子,現代公會的標配是
querySelector。它就像萬能定位儀,只要你懂一點 CSS 選擇器的邏輯,全場沒有你抓不到的標靶。學會這招,你就拿到了參與「DOM 實戰」的入場券。
天色微亮,營火雖已燃盡,但你眼中卻閃爍著領悟的光芒。在前往演武場挑戰關卡前,我已經幫你把靈魂碎片精煉成了這份「戰術錦囊」。拿好它,今日的任務不再是負擔,而是你證明自我的舞台。去吧,公會的英雄榜在等著你的戰報。
📝 【夥伴筆記:今日修煉精華】
這份筆記是你的隨身護身符,卡關時看一眼,真相就在裡面。
querySelector:抓取畫面上「第一個」符合條件的目標。querySelectorAll:全場擴散掃描,帶回一疊NodeList(類陣列清單)。textContent:操作標籤內的純文字台詞。value:獲取表單輸入框裡的機密數值。dataset:存取data-*自訂屬性的資料庫口袋。
🎯 【實戰演武場】
⚔️ 任務鑑定條件:
- 完成 📜 本日實戰任務 (CodePen)。
- 將 CodePen 網址貼至 QuestBoard,並回填鑑定報告:
- 初心者:捕獲 NPC 鑑定 (成就感發掘):
-
- 今天第一次在 Console 中成功印出瀏覽器上的標題時,有沒有一種「代碼終於與世界連接」的感覺?
-
- 冒險者:名單與陣列之謎 (理性挑戰):[⚡ 觀念辨析]
-
NodeList雖然長得像陣列,但它能直接施展map加工術嗎?
-
- 初心者:捕獲 NPC 鑑定 (成就感發掘):
- 任務完成後,你的名字將永遠標記在公會的英雄榜上!
📚 【圖書館卷軸與前後站連結】
- 前導冒險: Day 00: 勇者村的入村儀式
- 上一站冒險: Day 12:原理篇 —— 【邏輯開關】&&、|| 與 ?? 的短路判斷:老手最愛用的簡潔語法
- 下一站冒險: Day 14:原理篇 —— 事件監聽:當使用者點下去後,瀏覽器發生了什麼?
- MDN 官方文獻: MDN Document.querySelector() 詳解
- MDN 官方文獻: MDN Document.querySelectorAll() 詳解
- MDN 官方文獻: MDN 使用 data attributes 儲存自訂資料