iT邦幫忙

2026 iThome 鐵人賽

DAY 22
0
自我挑戰組

Vscode 實作:用 HTML/CSS/JS 打造醫藥健康小工具箱系列 第 22 篇

Day 22:【Tool 3 實作】單筆刪除與一鍵清空:事件代理 (Event Delegation) 與 confirm() 確認對話框應用

  • 分享至 

  • xImage
  •  

本篇文章目錄

  1. 前言:從資料驅動 UI 看互動設計
  2. 動態 DOM 綁定的挑戰:為什麼 querySelector 抓不到新元素?
  3. 解法介紹:事件代理 (Event Delegation) 與動態監聽綁定
  4. 程式碼實作:單筆刪除與一鍵清空
  5. 結語

1. 前言:從資料驅動 UI 看互動設計

在昨天的文章中,我們解決了 DOM 節點抓取(null 值存取錯誤)與 HTML 無障礙標籤(<label for="...">)的坑,成功讓「新增藥品卡片」的功能順利啟動。

有了新增,當然不能少了刪除!今天我們要完成 Tool 3 的最後一塊互動拼圖:

  • 單筆藥品刪除:點擊卡片右上角 ❌ 按鈕,刪除單一藥品並同步 LocalStorage。
  • 一鍵清空時間表:點擊重置按鈕清空當日所有用藥,並搭配 confirm() 二次確認機制。

2. 動態 DOM 綁定的挑戰:為什麼 querySelector 抓不到新元素?

在實作刪除按鈕時,前端新手最常碰到的問題是:

「明明在 JS 寫了 document.querySelectorAll('.btn-del').forEach(...),為什麼後續點按鈕『➕ 加入時間表』新增出來的藥品卡片,點擊 ❌ 卻完全沒有反應?」

核心原因:執行時間差

在網頁初始化執行 JavaScript 時,那些動態生成的藥品卡片根本還沒被建立!querySelectorAll 只會抓取「執行當下」已存在於 DOM 樹上的元素,對未來才產生的動態元素完全無能為力。

3. 解法介紹:事件代理 (Event Delegation) 與動態監聽綁定

針對動態生成的 DOM 元素,前端主要有兩種經典解法:

  1. 事件代理 (Event Delegation)

    將監聽器綁定在靜態存在 Parent 容器(例如 <table> 或卡片外層格)上,利用 JavaScript 的 事件冒泡 (Event Bubbling) 機制,當子元素被點擊時,由父元素統一捕捉並檢查 e.target。

  2. 動態生成時綁定 (Element-level Binding)

    在 JavaScript 使用 document.createElement() 建立卡片的當下,同步使用 .addEventListener() 為該卡片內部的按鈕綁定專屬點擊事件。

4. 程式碼實作:單筆刪除與一鍵清空

  1. 單筆刪除:Array.prototype.filter() 陣列過濾JavaScript

    刪除的思維不是直接去手動操作 DOM(.remove()),而是修改數據本身:

     chip.querySelector(".btn-del").addEventListener("click", (e) => {
      const idToDel = Number(e.target.getAttribute("data-id"));
      medList = medList.filter(item => item.id !== idToDel);
      saveAndRender();
    });
    

    💡 踩坑經驗提醒:HTML 中的 data-id 取出來為 String 型態,而 Date.now() 產生的 ID 為 Number 型態。若使用嚴格相等的過濾條件 !==,記得先透過 Number() 進行轉型!

  2. 原生 confirm() 防誤觸機制JavaScript

    清空全天時間表屬於毀滅性操作(Destructive Action),透過原生的 confirm() 方法進行攔截:

    if (confirm("確定要清空用藥時間表中的所有藥品嗎?此動作無法復原!")) {
        medList = [];
        saveAndRender();
    }
    

    confirm() 會暫停當前 JavaScript 執行緒並回傳布林值:點擊「確定」回傳 true,點擊「取消」回傳 false,簡單且有效率。

5. 結語:建立「單一真實數據源」的前端思考

今天我們完成了 Tool 3 的完整 CRUD(新增、讀取、刪除)互動流程。

透過這次實作可以體會到,保持 「單一真實數據源 (Single Source of Truth)」 的概念極為重要:

  • 永遠不要直接去改變畫面上的 DOM。
  • 資料 (Data) 才是核心:先操作 medList 陣列,最後統一呼叫 saveAndRender() 重新渲染 UI。

這樣不僅畫面與 LocalStorage 能達到 100% 同步,未來要加入「藥品排序」或「編輯備註」等進階功能時,也能輕鬆擴充。


上一篇
【Day 21】【Tool 3 實作】動態新增節點:document.createElement 與 appendChild 將藥品分派至對應時段格子
下一篇
Day 23:【CSS 技巧】列印樣式優化:用 @media print 自動帶入當日日期並一鍵乾淨列印成紙本
系列文
Vscode 實作:用 HTML/CSS/JS 打造醫藥健康小工具箱 共 25 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言