CHAPTER 26 · PRACTICE WORKSPACE

TODO A:CRUD、render、localStorage

完成可新增、切換與刪除且能保存的本機待辦事項 App

01 Starter 0/3
  1. 01Starter讀懂作品骨架
  2. 02Checkpoint 1加入第一項能力
  3. 03Checkpoint 2累積第二項能力
  4. 04Solution核對完整結果

TASK STATUS

三項任務目前狀態

TASK-01本階段處理

新增並安全顯示待辦事項

修改檔案:script.js

完成後看見:新增唯一 id 項目,輸入只會成為文字節點

TASK-02稍後處理

切換完成狀態

修改檔案:script.js

完成後看見:點擊完成可切換 done 並保存

TASK-03稍後處理

刪除並保存待辦事項

修改檔案:script.jsindex.html

完成後看見:刪除後重整頁面不會復活

WORKSPACE

本階段實作區

先確認作品目前能做什麼、還缺什麼,再從 TASK-01 開始修改。

FOCUS TASK · TASK-01

現在只處理:新增並安全顯示待辦事項

修改:script.js

完成後:新增唯一 id 項目,輸入只會成為文字節點

講解時展開:2 個小型比較

資料物件 vs DOM|先保存再渲染

比較:新增待辦先建立唯一 id 的資料,再由 render 產生安全畫面。

現在做:在 Checkpoint 1 清除 course-todos 後新增「買菜」,檢查 storage 物件含不同於空值的 idtext=買菜done=false;再新增 <img src=x onerror=alert(1)>,確認清單有 2 筆、兩個 id 不同且沒有產生 img。

看預期與證據

預期:storage 先有含唯一 id、text、done 的資料,render 再以安全文字節點呈現兩筆待辦。

證據:留下 course-todos 的資料物件、兩筆不同 id、清單文字與 img 計數 0 四項證據。

文字節點 vs HTML|輸入只當文字

比較:使用者輸入應成為文字節點,不能直接拼接成 HTML。

現在做:在 Checkpoint 1 新增 <img id='unsafe-todo' src=x onerror=alert(1)>,確認 #task-list span 顯示完整原始字串、#task-list img 數量為 0,並檢查 course-todos 的 text 仍是字串而非 HTML。

看預期與證據

預期:不建立 img 元素、不執行 onerror,輸入只存在於 span 的文字節點與 storage 字串。

證據:留下原始字串畫面、#task-list img 為 0、window.__xss 未設定與 storage text 四項證據。

需要排錯時查看:任務循環(觀察 → 預測 → 實作 → 故障 → 驗收)
  1. A|觀察:清除 `course-todos` 後開啟 Starter,輸入一筆文字並送出,確認 addTodo 尚未建立項目且清單維持空白。
  2. B|預測:先新增一筆正常待辦事項,再輸入 <img src=x onerror=alert(1)>;確認兩筆 id 不同,第二筆顯示原始文字且沒有產生 img 或跳出視窗。
  3. C|實作:在 script.js 的 loadTodos()、addTodo()、createTodoElement()、render() 完成「新增並安全顯示待辦事項」,一次只處理本任務責任。
  4. D|故障:若結果不一致,先依原操作重現,再檢查 loadTodos()、addTodo()、createTodoElement()、render() 與 script.js,最後重跑原操作。
  5. E|驗收:新增唯一 id 項目,輸入只會成為文字節點

完成條件:DONE-01:新增唯一 id 項目,輸入只會成為文字節點

我的待辦事項

    CONTINUE

    開始 TASK-01

    前往 Checkpoint 1,依要求完成「新增並安全顯示待辦事項」。

    前往 Checkpoint 1:完成 TASK-01

    CHAPTER HANDOFF

    從本機 CRUD,交棒到可復原的同步佇列

    接收第 25 章:沿用 owner/guest/unauth 的資料責任觀念;本章不共用 Auth runtime,改把「誰擁有資料」轉成每筆項目的唯一 id 與本機保存。

    交給第 27 章:完成後帶著 create、toggle、remove、safe render、`course-todos` 重整證據;下一章直接加入 queue、mock sender、offline 保留與 retry,不把 localStorage 說成同步。

    前往第 27 章:Mock 同步、失敗復原與 GAS 延伸