CHAPTER 18 · 240 MINUTES
Timer、狀態與重複啟動排錯
本章共 240 分鐘:課次 18 完成 Timer 核心,課次 19 前 60 分鐘專做重複 interval、清理與狀態不同步除錯。
LEARNING GOALS
本章結束時,你能做出什麼
01啟動前阻擋重複 timer
條件:按開始後至少等待三秒,再快速連按開始,確認仍然每秒只扣一。 驗收:每秒扣一且連按不加速,零時自動停止
02暫停後可從原秒數繼續
條件:倒數中按暫停、等待兩秒再繼續,確認秒數保留且可續跑。 驗收:暫停保留秒數,之後可繼續
03重設回初始值且倒數到零自動停止
條件:在倒數、暫停與歸零三種狀態按重設,確認都回到 10 秒。 驗收:任何狀態下都回到 10 秒與尚未開始
進場檢核與作品接力
- 具備第 17 章成果:slides[currentIndex] 經 renderSlide() 顯示、前後按鈕首尾循環、提示使用有效亂數索引:不看答案,展示第一張內容、末張按下一張回第一張、首張按上一張回末張,再抽出一項屬於 tips 陣列的提示。 需要補強時從這裡接回
- 能從 Starter、Checkpoint 與 Solution 中辨識目前工作階段:開啟本章主講義,指出 TASK-01 的修改檔案、可見結果與第一個 Checkpoint。 需要補強時從這裡接回
- 能用「操作後看見什麼」描述驗收證據:閱讀三個任務後,選一題說出操作條件與預期可見結果。 需要補強時從這裡接回
輸入:第 17 章產物:slides[currentIndex] 經 renderSlide() 顯示、前後按鈕首尾循環、提示使用 tips 的有效亂數索引;本章在獨立 timer 頁重用狀態改變後 render 的責任模式
本章輸出:可開始、暫停、重設且不會重複加速的倒數計時器
產物類型:mainline;後續用途:第 19 章
PROBLEM & ANALOGY
先理解責任,再寫語法
setInterval 像重複響的鬧鐘,timer id 是鬧鐘編號;暫停是關掉鬧鐘但保留秒數,重設則連秒數一起回到起點。
本章要解決:本章共 240 分鐘:課次 18 完成 Timer 核心,課次 19 前 60 分鐘專做重複 interval、清理與狀態不同步除錯。
接住上一章:第 17 章以 currentIndex 改變後呼叫 renderSlide() 管理輪播畫面;第 18 章在獨立 timer 頁把同一責任換成 remainingSeconds 與 renderTimer(),不共用第 17 章 HTML。
合回共同作品:本章成果必須回到同一份作品集檢查,不另開一個無關小作品。
必會能自己完成
啟動前阻擋重複 timer;暫停後可從原秒數繼續;重設回初始值且倒數到零自動停止。
辨識看得懂即可
能辨識 setTimeout 一次與 setInterval 重複的差別。
不教刻意延後
不教精密計時、背景分頁校正或非同步事件迴圈細節。
本章術語:setInterval、clearInterval、timer id、state、null、render。遇到英文先回到畫面責任,不要求背拼字。
- remainingSeconds 是資料,timerId 記錄有沒有計時器正在跑。
- 停止時同時 clearInterval 並把 timerId 設回 null。
- 所有秒數變化最後都呼叫
renderTimer(),避免資料與畫面不同步。
課堂刻意錯誤:先拿掉重複啟動防護,連按三次開始,觀察一秒扣三格;在 console 記錄三個 timer id 後修正。
- 連按會加速:啟動前檢查 timerId 是否不是 null。
- 暫停後不能再開始:檢查 clear 後是否設回 null。
- 重設只改畫面:確認 remainingSeconds 資料也回到初始值。
固定順序:先重現 → 讀 Console/Styles → 確認檔案與元素 → 一次只修一處 → 重跑原操作。
症狀 01
倒數越按越快
先查:檢查是否已有 interval,再看 start 是否清除舊 timer。
症狀 02
暫停後不能繼續
先查:確認 pause 保留秒數,resume 重新建立一個 timer。
症狀 03
重設後仍在倒數
先查:確認 reset clearInterval 且 timer id 已清空。
PRACTICE CONTRACT
Starter 到 Solution 是同一份骨架,任務一路加厚
開始前先確認這四件事
- 我已列出尚未開始、倒數、暫停與完成。
- 我知道 timer id 放在哪裡。
- 我會測試連按 start、pause、resume。
- 我會在任何狀態按 reset。
TASK-01
啟動單一 interval 並倒數到零
檔案:script.js
位置:startButton 的 click handler(TASK-01 區塊)
結果:每秒扣一且連按不加速,零時自動停止
TASK-02
完成可再次開始的暫停
檔案:script.js
位置:pauseButton 的 click handler 與 stopTimer()(TASK-02 區塊)
結果:暫停保留秒數,之後可繼續
TASK-03
重設資料、timer 與畫面
檔案:script.js
位置:resetButton 的 click handler(TASK-03 區塊)
結果:任何狀態下都回到 10 秒與尚未開始
-
01
先讀任務
Starter
讀任務、先預測結果。
累積完成 0/3 個任務
開始練習 →
-
02
完成第一項
Checkpoint 1
完成 TASK-01。
累積完成 1/3 個任務
繼續第一步 →
-
03
累積第二項
Checkpoint 2
再完成 TASK-02。
累積完成 2/3 個任務
繼續第二步 →
-
04
核對完成品
Solution
只補 TASK-03,不重構既有骨架。
累積完成 3/3 個任務
查看完整結果 →
✓網頁版答案位置對照卡住時先完成 Checkpoint 2,再查看每個 TASK 對應的檔案與位置。→
30 秒說法可以直接照這個句型練習:
目前 state 是 ______;timer id ______ 代表 ______;reset 會先 ______,再 ______。
時間功能證據要包含生命週期;只截一張數字畫面無法證明沒有重複 timer。
現場快速連按開始、暫停後繼續、最後重設;口頭說明 remainingSeconds、timerId 與 renderTimer() 的不同責任。
交件前自我檢核
5 項 · 點選每一列完成自評
下一章:第 19 章會閱讀舊站 jQuery,對照相同的事件與 class 狀態概念。
下一步:前往第 19 章「舊站維護:jQuery 與 FAQ 對照」,帶著本章輸出繼續累積作品。