LESSON-17 · 零基礎學生教材
JavaScript 基礎:事件、行動版選單與 FAQ
完成行動版選單與 FAQ 開合:按鈕能接收滑鼠或鍵盤操作,DOM 的 aria-expanded、aria-controls、hidden 與實際畫面狀態一致,services.html 只作為連結目的頁。
先理解:這堂課解決什麼問題?
多頁網站在手機上需要可開關導覽,FAQ 也要能讓訪客逐項展開而不重新整理頁面;本堂先用一個入口頁和一個目的頁,讓每個狀態都能在瀏覽器中看見。
本堂要完成:完成行動版選單與 FAQ 開合:按鈕能接收滑鼠或鍵盤操作,DOM 的 aria-expanded、aria-controls、hidden 與實際畫面狀態一致,services.html 只作為連結目的頁。
學習邊界:先完成「用事件監聽完成行動版選單與 FAQ 開合」,不提前引入尚未教過的框架或建置工具。
先備知識與操作環境
本堂先備:不要求先會 JavaScript 事件。只要知道如何在編輯器儲存檔案、用瀏覽器開啟 HTML、按滑鼠或鍵盤、按右鍵開啟 DevTools 的 Elements、Console、Network。先依序開啟 examples/minimal.html,再開始 Starter;本堂只使用原生 HTML、CSS、JavaScript,不加入框架、API 或建置工具。
- 檔案位置:先找到
examples/minimal.html、starter/files/index.html、starter/files/main.js、checkpoint/files/main.js、solution/files/main.js、services.html,再從本頁的最小實驗開始。 - 瀏覽器:開啟最小實驗與階段頁;每次修改後儲存並重新整理。
- DevTools:依本堂內容使用 Elements、Styles、Computed、Console 或 Network,記下第一個可觀察證據。
- 操作習慣:每次只修改一個檔案或一個責任,先預測、再操作、最後驗收。
先做最小實驗:先看見結果
這不是期末網站,而是一個可以直接看到本堂核心結果的最小實驗。先完成一次操作,再回到檔案和名詞卡對照。
- 入口:開啟
examples/minimal.html。 - 操作:先按「開啟選單」,觀察 nav 出現與 aria-expanded 變成 true;再用 Tab 走到 FAQ,按 Enter 或 Space 展開兩題,最後在 Elements 比對每個 button 的 aria-controls 和答案 id。
- 預期:選單開合時 nav.hidden、aria-expanded、按鈕文字一致;每個 FAQ 答案會依自己的 aria-controls 展開或收合,頁面不重新整理且 Console 沒有錯誤。
- 重設:重新整理
examples/minimal.html;初始 nav 和兩個 FAQ answer 都有 hidden,所有 button 的 aria-expanded 都是 false。
學生練習流程
依序完成每一張卡;目前只聚焦一個步驟,先操作,再用可觀察證據確認結果。
-
1
最小實驗
先閱讀本頁的問題、檔案地圖、名詞卡與最小例子。 -
2
Step 2
自己回答互動問答 4 題,再展開解析。 -
3
最小實驗 2
開啟最小實驗,實際操作一次並記下證據。 -
4
Starter
把 Starter 複製到自己的工作資料夾,照 3 張微步驟卡逐一完成;每一步都要看到結果再繼續。 -
5
Checkpoint
前往 Checkpoint,只處理 1 個本堂核心缺口;先預測,再用指定證據驗收。 -
6
Solution
前往 Solution,先看逐檔差異與修改原因,再決定要不要把完整內容帶回自己的檔案。 -
7
變體驗收
完成情境變體與獨立挑戰,留下檔案位置、操作、結果與驗收證據,並閱讀下一堂銜接:表單非同步:下一堂會將事件處理延伸到驗證與送出狀態。
檔案地圖:每個位置負責什麼?
先不要急著背檔名;請把檔案位置和責任連起來。你在階段頁會看到同一份檔案的可執行版本。
examples/minimal.html只讀最小實驗:先看完整的選單與 FAQ 事件結果,再回到名詞卡。starter/files/index.htmlStarter 入口:HTML scaffold 已完成,包含 menuButton、site-nav、FAQ button、answer 與 aria 關係。starter/files/main.jsStarter JavaScript:只有三個 TODO,依序完成狀態同步、menu click listener、FAQ click listener。checkpoint/files/main.jsCheckpoint JavaScript:故意漏掉 siteNav.hidden,重現 ARIA 變了但畫面沒有開的缺口。solution/files/main.jsSolution JavaScript:完整同步 aria-expanded、按鈕文字、nav.hidden 與 FAQ answer.hidden。services.html目的頁:驗收相對路徑與檔案責任,不載入首頁互動腳本。
先學會這些詞
先從名詞、英文與白話意思開始;每次只展開一張名詞卡,再對照正式定義、範例與驗收證據。專業術語、語法、檔案路徑會使用不同樣式。第一次遇到術語時,先回到這裡,不要靠猜。
文件與 DOM
8 個詞瀏覽器browser 白話意思:把 HTML、CSS 與 JavaScript 讀成可以看的網頁,並回應你的操作。 展開查看正式定義、範例與驗收證據
- 正式定義
- 解析文件、建立 DOM、套用 CSS,並在目前頁面執行 JavaScript 的用戶端軟體。
- 什麼時候用
- 要預覽檔案、點擊按鈕、按鍵盤或打開 DevTools 時。
- 最小範例
- Chrome 開啟 starter/files/index.html 後,會建立畫面並載入 main.js。
- 可觀察證據
- 畫面、Elements、Console 與 Network 四個位置看到的實際結果。
- 容易混淆
- 和編輯器混淆;編輯器修改檔案,瀏覽器呈現與執行檔案。
HTMLHyperText Markup Language 白話意思:描述頁面有哪些內容,以及內容之間的結構。 展開查看正式定義、範例與驗收證據
- 正式定義
- 以元素與屬性描述文件結構,讓瀏覽器建立可操作的文件。
- 什麼時候用
- 要放按鈕、導覽、FAQ 問題與答案時。
- 最小範例
- <button id="menuButton" type="button">開啟選單</button> 建立一個按鈕元素。
- 可觀察證據
- Elements 能看到按鈕、nav、FAQ answer 的階層與屬性。
- 容易混淆
- 和 CSS 混淆;HTML 決定內容與結構,CSS 決定呈現方式。
CSSCascading Style Sheets 白話意思:控制頁面內容怎麼排列、顯示或隱藏。 展開查看正式定義、範例與驗收證據
- 正式定義
- 以規則選取 HTML 元素並設定呈現樣式的語言。
- 什麼時候用
- 要讓選單在
hidden時不佔畫面,或讓按鈕有清楚的 focus 時。 - 最小範例
- nav[hidden] { display: none; } 讓 hidden 的導覽不顯示。
- 可觀察證據
- Styles/Computed 與實際畫面、鍵盤 focus 的前後差異。
- 容易混淆
- 和 JavaScript 混淆;CSS 呈現狀態,JavaScript 負責在事件後更新狀態。
JavaScriptJavaScript 白話意思:讓網頁在載入後能讀取畫面、等待操作並改變結果的程式語言。 展開查看正式定義、範例與驗收證據
- 正式定義
- 可在瀏覽器中讀取與修改 DOM、註冊事件並執行程式流程的語言。
- 什麼時候用
- 要讓 click 發生後選單開啟,或 FAQ 答案出現時。
- 最小範例
- menuButton.addEventListener("click", handleMenuClick); 等待按鈕被點擊。
- 可觀察證據
- 點擊/按鍵後的畫面、Elements 屬性與 Console 訊息。
- 容易混淆
- 和 HTML/CSS 混淆;JavaScript 不取代 HTML 結構,也不只是改顏色。
DOMDocument Object Model 白話意思:瀏覽器把 HTML 解析成 JavaScript 可以找到與修改的文件樹。 展開查看正式定義、範例與驗收證據
- 正式定義
- 代表目前文件節點、階層、屬性與內容狀態的程式介面。
- 什麼時候用
- 要找到 menuButton、site-nav、FAQ answer,或修改 hidden 時。
- 最小範例
- document.querySelector("#site-nav") 找到目前文件中的 nav 元素。
- 可觀察證據
- Elements 看到的 DOM 和 JavaScript 操作後的畫面、屬性一致。
- 容易混淆
- 和編輯器中的原始 HTML 文字混淆;DOM 是瀏覽器目前正在使用的結果。
元素element 白話意思:頁面中的一個完整內容單位,例如 button、nav 或 p。 展開查看正式定義、範例與驗收證據
- 正式定義
- 瀏覽器建立的文件節點,通常由 HTML 標籤、內容與屬性形成。
- 什麼時候用
- 要說明 JavaScript 找到或修改的是哪一個頁面單位時。
- 最小範例
- document.querySelector("#menuButton") 回傳一個 button 元素。
- 可觀察證據
- Elements 能選取該元素並查看它的標籤、文字與屬性。
- 容易混淆
- 和標籤混淆;標籤是 HTML 的寫法,元素是瀏覽器建立的節點單位。
屬性attribute 白話意思:寫在 HTML 開始標籤裡,提供元素額外設定的名稱和值。 展開查看正式定義、範例與驗收證據
- 正式定義
- 元素上的
name/value資訊,可由瀏覽器、CSS 或 JavaScript 讀取與更新。 - 什麼時候用
- 要讓按鈕連到答案,或表達目前開合狀態時。
- 最小範例
- aria-controls="faq-answer-1" 指出按鈕控制哪一個答案。
- 可觀察證據
- Elements 的 Attributes 區能看到
aria-controls、aria-expanded、hidden。 - 容易混淆
- 和 CSS property 混淆;attribute 寫在 HTML 元素上,property 是 CSS 規則中的設定。
selectorselector 白話意思:告訴 JavaScript 要找哪一個元素的寫法。 展開查看正式定義、範例與驗收證據
- 正式定義
- 用來匹配文件元素的模式;本堂先使用
#id與 attribute selector。 - 什麼時候用
- 要把 JavaScript 連到特定按鈕、nav 或一組 FAQ 按鈕時。
- 最小範例
- #menuButton 找一個 id;[data-faq-button] 找一組 FAQ button。
- 可觀察證據
- selector 找到的元素不是 null,且 Elements 中的 id/attribute 真的存在。
- 容易混淆
- 和 property 混淆;selector 決定找誰,property/attribute 決定要讀取或改變什麼。
事件與狀態
7 個詞functionfunction 白話意思:把一組有名字的步驟包起來,需要時再執行。 展開查看正式定義、範例與驗收證據
- 正式定義
- 可接收參數並執行一段可重複使用程式的 JavaScript 單位。
- 什麼時候用
- 要把『同步選單狀態』和『監聽點擊』拆成兩個清楚責任時。
- 最小範例
- function setMenuOpen(isOpen) { siteNav.hidden = !isOpen; } 定義一個狀態更新 function。
- 可觀察證據
- 檔案中能找到
function定義,事件發生後畫面與 DOM 真的改變。 - 容易混淆
- 和
functioncall 混淆;宣告只是準備步驟,呼叫才會執行步驟。
callbackcallback function 白話意思:先交給瀏覽器,等事件發生後再執行的函式。 展開查看正式定義、範例與驗收證據
- 正式定義
- 作為參數傳給事件註冊方法,由事件系統在指定事件發生時呼叫的函式。
- 什麼時候用
- 要把 click 發生後的處理交給
addEventListener時。 - 最小範例
- button.addEventListener("click", () => { /* 事件發生後才執行 */ });。
- 可觀察證據
- 註冊當下沒有立刻改變畫面,點擊後才看到狀態變化。
- 容易混淆
- 和立即呼叫混淆;
handle()會現在執行,handle才是交給瀏覽器的function。
事件event 白話意思:使用者或瀏覽器發生的一件事。 展開查看正式定義、範例與驗收證據
- 正式定義
- 瀏覽器派送給事件目標、可被監聽與處理的互動通知。
- 什麼時候用
- 按鈕被點擊、鍵盤按 Enter/Space,或表單送出時。
- 最小範例
- 按下 menuButton 會產生一個 click event。
- 可觀察證據
- 操作前後的畫面、DOM 屬性、Console 訊息與 URL。
- 容易混淆
- 和
function混淆;事件是發生的時機,function是發生後要做的步驟。
addEventListeneraddEventListener 白話意思:告訴瀏覽器某種事件發生時要執行哪一個 callback。 展開查看正式定義、範例與驗收證據
- 正式定義
- 在 EventTarget 上註冊指定事件類型與 callback
function的方法。 - 什麼時候用
- 要讓 button 的 click 行為集中在 JavaScript,而不是寫成 HTML onclick 時。
- 最小範例
- menuButton.addEventListener("click", handleMenuClick);。
- 可觀察證據
- 點擊或鍵盤操作後,正確的元素與狀態才會改變;Console 沒有錯誤。
- 容易混淆
- 和直接呼叫
function混淆;註冊 listener 是等待,不是現在立刻執行。
hiddenhidden attribute 白話意思:讓元素目前不顯示,也不讓使用者操作。 展開查看正式定義、範例與驗收證據
- 正式定義
- HTML 的布林屬性;存在時表示元素目前不應呈現給使用者。
- 什麼時候用
- 要控制行動版 nav 或 FAQ answer 的真實可見性時。
- 最小範例
- siteNav.hidden = !isOpen; 依開合狀態顯示或隱藏導覽。
- 可觀察證據
- Elements 的
hidden屬性與畫面可見性同步;按 Tab 也不會進入隱藏內容。 - 容易混淆
- 和只改 class 混淆;class 可以影響樣式,但本堂用 hidden 表達真正的顯示狀態。
aria-expandedaria-expanded 白話意思:告訴輔助技術某個控制項目前是開啟還是關閉。 展開查看正式定義、範例與驗收證據
- 正式定義
- ARIA state,用於表示由控制項控制的可展開區域目前是否展開。
- 什麼時候用
- 按鈕會開合 nav 或 FAQ answer 時。
- 最小範例
- button.setAttribute("aria-expanded", String(isOpen));。
- 可觀察證據
- Elements 的值與畫面、hidden 狀態前後一致;初始值是
false。 - 容易混淆
- 和 hidden 混淆;aria-expanded 說明狀態,hidden 負責讓目標實際隱藏。
aria-controlsaria-controls 白話意思:告訴輔助技術這個按鈕控制哪一個元素。 展開查看正式定義、範例與驗收證據
- 正式定義
- ARIA relationship,透過目標元素的 id 指出控制關係。
- 什麼時候用
- 一個 button 要控制 nav 或多個 FAQ answer 中的一個時。
- 最小範例
- button 的 aria-controls="faq-answer-1" 對應 <p id="faq-answer-1">。
- 可觀察證據
- 逐字比對 button 的值和目標元素 id;沒有指向不存在的元素。
- 容易混淆
- 和 href 混淆;href 是連結目的地,aria-controls 是控制關係的說明。
載入與驗收
2 個詞deferscript defer 白話意思:讓外部 JavaScript 等 HTML 解析完成後再執行。 展開查看正式定義、範例與驗收證據
- 正式定義
- script 的布林屬性;外部腳本可下載,並在文件解析完成後依序執行。
- 什麼時候用
main.js需要找到 body 裡的按鈕與 nav,又想維持獨立 JavaScript 檔案時。- 最小範例
- <script src="main.js" defer></script>。
- 可觀察證據
- Network 可看到
main.js成功載入,Console 沒有因目標尚未建立而出現的 null 錯誤。 - 容易混淆
- 和 async 混淆;本堂用 defer 讓 HTML 順序與 JavaScript 執行時機可預測。
DevToolsDeveloper Tools 白話意思:瀏覽器裡用來看頁面真實狀態與找錯誤的工具箱。 展開查看正式定義、範例與驗收證據
- 正式定義
- 提供 Elements、Console、Network 等面板,以檢查執行中頁面與資源請求的開發工具。
- 什麼時候用
- 畫面和預期不同,或需要證明是 DOM、JavaScript 還是檔案路徑出錯時。
- 最小範例
- 按右鍵選檢查,在 Elements 查看 hidden,在 Console 找紅色錯誤,在 Network 查 main.js/services.html。
- 可觀察證據
- Elements 的屬性、Console 的錯誤、Network 的狀態碼與實際畫面互相印證。
- 容易混淆
- 和編輯器混淆;編輯器改來源檔,DevTools 查瀏覽器目前結果。
最小例子:先看懂,再複製
這段只保留本堂第一個微成果。先預測結果,再逐行讀;完整檔案請開啟下方最小實驗。
function setMenuOpen(isOpen) {
menuButton.setAttribute("aria-expanded", String(isOpen));
menuButton.textContent = isOpen ? "關閉選單" : "開啟選單";
siteNav.hidden = !isOpen;
}Live Lab:逐段讀碼與驗證
每一步只回答五件事:為什麼做、改哪裡、會看到什麼、用什麼證據確認、卡住先查什麼。
-
Step 1
先讀懂一個狀態的三個出口
- 目的
- 把選單開啟狀態拆成按鈕屬性、按鈕文字與 nav.hidden,先建立『狀態要同步』的概念。
- 修改位置
starter/files/main.js的 setMenuOpen(isOpen)
在 setMenuOpen 內保留 aria-expanded 與按鈕文字,再補上 siteNav.hidden = !isOpen。- 預期結果
- 只讀
function就能說出 isOpen=true 時 nav 應顯示、按鈕文字應變成關閉選單;尚未註冊事件前,重新整理不會自動開啟。 - 驗收證據
- Elements 的 aria-expanded、button.
textContent、nav.hidden,以及畫面前後狀態。 - 卡住先查
- 只搜尋 setMenuOpen 內是否同時出現 aria-expanded、
textContent與 hidden。
-
Step 2
把 click 事件交給 callback
- 目的
- 理解
addEventListener先註冊、事件發生後才呼叫 callback;不把functioncall 寫在註冊當下。 - 修改位置
starter/files/main.js的 menuButton click listener
註冊 menuButton 的 click listener,讀取目前 aria-expanded,再把反轉後的值交給 setMenuOpen。- 預期結果
- 滑鼠點擊、鍵盤 Enter 與 Space 都能讓選單開合;每次操作後 Elements 和畫面狀態一致。
- 驗收證據
- 按鈕滑鼠/鍵盤操作、aria-expanded、hidden、按鈕文字與 Console 無錯誤。
- 卡住先查
- 只看
addEventListener的第二個參數;它應該是一個function,而不是呼叫後的結果。
-
Step 3
用 aria-controls 找到每一題答案
- 目的
- 把同一個事件流程移植到多個 FAQ,理解每個按鈕要依自己的控制關係找到對應答案。
- 修改位置
starter/files/main.js的 faqButtons.forEach
對每個 FAQ button 註冊 click,讀取 aria-controls,找到同 id 的 answer,再同步 aria-expanded 與 answer.hidden。- 預期結果
- 第一題只開第一題答案,第二題只開第二題答案;兩題可以同時展開,頁面不跳轉。
- 驗收證據
- 每個 button 的 aria-controls、對應 answer id、aria-expanded、hidden、畫面與鍵盤結果。
- 卡住先查
- 先只比對目前 button 的 aria-controls 和 document.
querySelector組出的 id。
-
Step 4
從『屬性變了』找出畫面仍不見的 bug
- 目的
- 讓學生重現一個真實的狀態同步缺口:ARIA 已更新不代表 nav 實際已顯示。
- 修改位置
checkpoint/files/main.js的 setMenuOpen(isOpen)
只補上 siteNav.hidden = !isOpen,不重寫 listener、不改用 class、不修改 HTML scaffold。- 預期結果
- 修正前點擊後 aria-expanded=true 但 nav 仍隱藏;修正後 nav 可見,再點一次可收合。
- 驗收證據
- 修正前後的 Elements、畫面可見性、按鈕文字、aria-expanded 與 nav.hidden。
- 卡住先查
- 只查看 setMenuOpen 的三個同步位置,確認 hidden 是否使用反轉後的 isOpen。
-
Step 5
用 defer、Network 與目的頁完成回歸驗收
- 目的
- 把互動正確和資源路徑正確分開驗收,避免只看到畫面就忽略 script 或連結錯誤。
- 修改位置
solution/files/index.html、solution/files/main.js、solution/files/services.html
重新整理index.html,檢查 script 的 defer、Network 的main.js/services.html請求,再直接開啟services.html。- 預期結果
index.html的操作無 TypeError;services.html是只讀目的頁、不載入互動main.js,也沒有因 menuButton 不存在而出現錯誤。- 驗收證據
- Network 的資源狀態、Console、HTML 的 defer、
services.html的 script 清單與連結 URL。 - 卡住先查
- 先開啟
services.html,搜尋它是否包含main.js;再回到index.html檢查 defer。
-
Step 6
整合本堂驗收證據
- 目的
- 把前面完成的修改放回本堂任務,確認不是只修好單一畫面。
- 修改位置
examples/minimal.html與本堂驗收證據
依序檢查 Starter、Checkpoint、Solution 與最小實驗可開啟;選單和 FAQ 的 aria-controls、aria-expanded、hidden、鍵盤Enter/Space、Console 與services.html路徑都能留下證據,只記錄一個實際觀察,不新增本堂以外的技術。- 預期結果
- 完成行動版選單與 FAQ 開合:按鈕能接收滑鼠或鍵盤操作,DOM 的 aria-expanded、aria-controls、hidden 與實際畫面狀態一致,
services.html只作為連結目的頁。 - 驗收證據
- Starter、Checkpoint、Solution 與最小實驗可開啟;選單和 FAQ 的 aria-controls、aria-expanded、hidden、鍵盤
Enter/Space、Console 與services.html路徑都能留下證據 - 卡住先查
- 先確認目前 URL 是
examples/minimal.html,再在 Elements 選取 #menuButton、#site-nav 與第一個 [data-faq-button]。
讀碼順序:先找入口,再用畫面、Elements、Console、Network 與鍵盤驗證;本堂每個互動都要同時說明事件、目標元素、aria 狀態與 hidden 可見性。
互動問答
先回答目前這一題,再展開解析;完成後按下一題,讓每一次回答都回到檔案或瀏覽器完成驗證。
Q1概念理解 「瀏覽器(browser)」在本堂要解決什麼問題? 本題線索:瀏覽器;回到名詞卡與 畫面、Elements、Console 與 Network 四個位置看到的實際結果。 展開解析收合解析
白話解析:
把 HTML、CSS 與 JavaScript 讀成可以看的網頁,並回應你的操作。 正式來說,解析文件、建立 DOM、套用 CSS,並在目前頁面執行 JavaScript 的用戶端軟體。
對照位置:
回到名詞卡「瀏覽器」,再看 畫面、Elements、Console 與 Network 四個位置看到的實際結果。
預期觀察:
你應該能用自己的話說出:要預覽檔案、點擊按鈕、按鍵盤或打開 DevTools 時。
常見錯誤:
不要只回答「它是瀏覽器」;那是重複名詞,不是說明責任。
立即驗證:
開啟 examples/minimal.html,依序做「先按「開啟選單」,觀察 nav 出現與 aria-expanded 變成 true;再用 Tab 走到 FAQ,按 Enter 或 Space 展開兩題,最後在 Elements 比對每個 button 的 aria-controls 和答案 id。」並記下畫面或工具證據。
Q2程式碼閱讀
修改指定規則後,你預測畫面會看到什麼?
本題線索:starter/files/main.js 的 setMenuOpen(isOpen);要修改:在 setMenuOpen 內保留 aria-expanded 與按鈕文字,再補上 siteNav.hidden = !isOpen。;觀察:Elements 的 aria-expanded、button.textContent、nav.hidden,以及畫面前後狀態。
展開解析收合解析
白話解析:
先看檔案責任,再預測結果。這一步的目的:把選單開啟狀態拆成按鈕屬性、按鈕文字與 nav.hidden,先建立『狀態要同步』的概念。
對照位置:
對照 Live Lab Step 1,位置是 starter/files/main.js 的 setMenuOpen(isOpen);範例內容:function setMenuOpen(isOpen) {
menuButton.setAttribute("aria-expanded", String(isOpen));
menuButton.textContent = isOpen ? "關閉選單" : "開啟選單";
siteNav.hidden = !isOpen;
}
預期觀察:
只讀 function 就能說出 isOpen=true 時 nav 應顯示、按鈕文字應變成關閉選單;尚未註冊事件前,重新整理不會自動開啟。
常見錯誤:
如果只改了檔案但沒有結果,先不要重寫全部;只搜尋 setMenuOpen 內是否同時出現 aria-expanded、textContent 與 hidden。
立即驗證:
實際操作後檢查 Elements 的 aria-expanded、button.textContent、nav.hidden,以及畫面前後狀態。。
Q3概念比較
「瀏覽器」和「HTML」在本堂的責任有什麼不同?
本題線索:比較 瀏覽器 與 HTML;操作位置:starter/files/main.js 的 menuButton click listener
展開解析收合解析
白話解析:
瀏覽器:把 HTML、CSS 與 JavaScript 讀成可以看的網頁,並回應你的操作。;HTML:描述頁面有哪些內容,以及內容之間的結構。
對照位置:
對照兩張名詞卡的正式定義:解析文件、建立 DOM、套用 CSS,並在目前頁面執行 JavaScript 的用戶端軟體。/以元素與屬性描述文件結構,讓瀏覽器建立可操作的文件。
預期觀察:
你應該能指出兩者分別出現在哪個檔案或工具,以及哪一個結果會改變。
常見錯誤:
不要把「改變畫面」當成所有技術的責任;先說清楚誰負責結構、呈現、行為或驗收。
立即驗證:
在 starter/files/main.js 的 menuButton click listener 做「註冊 menuButton 的 click listener,讀取目前 aria-expanded,再把反轉後的值交給 setMenuOpen。」,再用 按鈕滑鼠/鍵盤操作、aria-expanded、hidden、按鈕文字與 Console 無錯誤。 比較前後差異。
Q4除錯驗收
如果完成操作後結果不對,你會先從哪一個證據開始查?
本題線索:solution/files/index.html、solution/files/main.js、solution/files/services.html;第一個檢查位置:Network 的資源狀態、Console、HTML 的 defer、services.html 的 script 清單與連結 URL。
展開解析收合解析
白話解析:
先描述症狀,再提出一個最小假設。本堂常見錯誤是:為了讓 services.html 不報錯,在 main.js 到處加不必要的 null 分支,或把所有互動腳本複製到每一頁。
對照位置:
對照最後一段 Live Lab:solution/files/index.html、solution/files/main.js、solution/files/services.html;檢查方式:先開啟 services.html,搜尋它是否包含 main.js;再回到 index.html 檢查 defer。
預期觀察:
你要能指出一個具體位置,而不是一次修改很多檔案。
常見錯誤:
不要先清快取、重裝工具或複製 Solution;先查看第一個可觀察錯誤。
立即驗證:
重新操作並留下「症狀、證據、假設、單一修正、結果」五項紀錄。
常見誤解
- 看到畫面沒有變化,不代表程式沒執行;先確認檔案、路徑、元素與狀態證據。
- 能複製 Solution 不代表理解;請先說出修改哪個檔案、預期哪個結果、用什麼證據確認。
- 本堂只使用既定的 HTML、CSS、JavaScript、Vue CDN、Apps Script mock 與 Cloudflare Pages 驗收範圍。
本堂任務與驗收
完成行動版選單與 FAQ 開合:按鈕能接收滑鼠或鍵盤操作,DOM 的 aria-expanded、aria-controls、hidden 與實際畫面狀態一致,services.html 只作為連結目的頁。
- 能用 Starter 留下可重現證據。
- 能用 Checkpoint 留下可重現證據。
- 能用 Solution 與最小實驗可開啟;選單和 FAQ 的 aria-controls 留下可重現證據。
- 能用 aria-expanded 留下可重現證據。
- 能用 hidden 留下可重現證據。
- 能用 鍵盤
Enter/Space留下可重現證據。 - 能用 Console 與
services.html路徑都能留下證據 留下可重現證據。 - Starter、Checkpoint、Solution 的入口都能開啟並知道三者差異。
- 遇到問題時能先寫出症狀,再檢查一個最小假設。