網站的「常見問題(FAQ)」頁面,若把所有答案一次攤開會讓頁面顯得很混亂。「手風琴折疊元件」讓使用者點擊標題時才展開對應答案,是維持介面整潔的好幫手。
querySelectorAll + forEach:一次選取多個相同的 DOM 元素,並用迴圈批次為它們綁定事件監聽器。nextElementSibling:精準取得點擊目標「緊鄰的下一個 DOM 節點」,就不用去為每個答案區塊設定獨立 ID 。1. document.querySelectorAll('.accordion-header') 與 forEach()
為什麼選用這個函式
手風琴選單通常有多個題目(例如 3 個 FAQ 標題)。querySelectorAll 可以一次選取畫面上所有帶有指定 Class 的元素,並回傳一個 NodeList 清單;再搭配 forEach() 迴圈,就能批次為每一個標題綁定點擊事件。
這個函式在幹嘛
querySelectorAll 在整頁找尋匹配 CSS 選擇器的元素集;forEach 則是逐一走訪集合中的每個項目。
有沒有其他替代方案
<ul> 上,透過 event.target 判斷點擊目標。querySelectorAll + forEach 邏輯最直覺好懂。2. element.nextElementSibling 屬性
為什麼選用這個屬性
點擊標題時,我們需要去控制「緊接在標題後面的內容區塊」。nextElementSibling 可以直接準確抓到下一個同階層的 HTML 元素,完全不用為每個內容區塊獨立命名 ID!
這個屬性在幹嘛
在 DOM 樹狀結構中尋找同一層級的「下一個相鄰元素」。
有沒有其他替代方案
querySelector('.accordion-content')
nextElementSibling 才是針對相對位置操作。<!DOCTYPE html>
<html lang="zh-TW">
<head>
<meta charset="UTF-8">
<title>第五課 - 手風琴式 FAQ 折疊選單</title>
<style>
body { font-family: sans-serif; padding: 40px; background-color: #f4f6f8; }
.accordion { width: 400px; margin: 0 auto; }
/* FAQ 標題樣式 */
.accordion-header {
background-color: #007bff;
color: white;
padding: 15px;
cursor: pointer;
border-radius: 4px;
margin-top: 10px;
user-select: none;
}
/* FAQ 內容區塊樣式 (預設隱藏) */
.accordion-content {
background-color: white;
padding: 0 15px;
max-height: 0; /* 初始高度為 0 */
overflow: hidden; /* 超出高度時隱藏 */
transition: max-height 0.3s ease, padding 0.3s ease; /* 平滑展開動畫 */
border-radius: 0 0 4px 4px;
}
/* 展開狀態下的 CSS 類別 */
.accordion-content.active {
max-height: 200px; /* 設定適當的最大高度來讓它滑出 */
padding: 15px;
}</style>
</head>
<body>
<div class="accordion">
<h2>常見問題 FAQ</h2>
<div class="accordion-header">Q1: 這個課程適合完全零基礎嗎?</div>
<div class="accordion-content">是的!本系列專為學過語法卻不會實作的初學者設計,從基礎 DOM 開始帶你動手做。</div>
<div class="accordion-header">Q2: 寫網頁需要安裝很複雜的軟體嗎?</div>
<div class="accordion-content">完全不需要,只需要安裝 VS Code 編輯器與 Google Chrome 瀏覽器即可。</div>
<div class="accordion-header">Q3: 完成 30 天後我能做出什麼?</div>
<div class="accordion-content">你將掌握常用網頁 UI 元件、API 資料串接,並建立屬於自己的 GitHub 作品集網頁!</div>
</div>
<script>
// ----------------------------------------------------
// JavaScript 邏輯 (DOM 操作)
// ----------------------------------------------------
// 第一步:取得畫面上所有的 .accordion-header 標題按鈕
const headers = document.querySelectorAll(".accordion-header");
// 第二步:使用 forEach 迴圈,為每一個標題綁定點擊事件
headers.forEach(function(header){
header.addEventListener("click", function(){
// 第三步:找到目前點擊標題的下一個同階層元素 (即對應的 .accordion-content)
const content = header.nextElementSibling;
// 第四步:使用 classList.toggle 切換 'active' 類別
// 有 active 類別時展開,沒有時收合
content.classList.toggle("active");
});
});</script>
</body>
</html
透過 DOM 的相對位置比對(nextElementSibling)與 CSS max-height 動畫配合,我們就能打造既美觀又具備平滑展開效果的組件。這種相對節點存取的技巧,未來在側邊多層級選單、購物車數量加減等情境中都會頻繁使用。
使用者在輸入社群貼文或評論時,網站常會顯示「剩餘字數提示」或「超過字數變紅」。這即時視覺反饋是怎麼做出來的
【第六課】視覺反饋:字數計數器與上限提示(keyup 與樣式控制)。