首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

JavaScript 實現多表格全選/全不選:統一事件委託與名稱分組最佳實踐

     編輯:程式設計綜合問答

場景痛點

頁面存在多個獨立 <table>,每個表格表頭有「全選」 Checkbox,tbody 每行有子 Checkbox。傳統寫法為每個表格寫獨立 ID、綁定獨立事件,代碼冗余、難維護。

核心設計:名稱分組 + 事件委託

  • 所有「全選」 Checkbox 共用 name="checkAll"。
  • 第 N 個表格的子 Checkbox 共用 name="itemGroup{N}"(或 data-group="N")。
  • 「全選」 Checkbox 綁定 data-target="itemGroup{N}" 指明控制哪組。

HTML 結構示例

<table class="data-table">
  <thead>
    <tr><th><input type="checkbox" name="checkAll" data-target="items1"> 全選</th>...</tr>
  </thead>
  <tbody>
    <tr><td><input type="checkbox" name="items1" value="1"></td>...</tr>
    ...
  </tbody>
</table>

<table class="data-table">
  <thead>
    <tr><th><input type="checkbox" name="checkAll" data-target="items2"> 全選</th>...</tr>
  </thead>
  <tbody>
    <tr><td><input type="checkbox" name="items2" value="1"></td>...</tr>
  </tbody>
</table>

統一 JavaScript 實現

// 事件委託:綁在 document 或共同祖先
document.addEventListener('change', e => {
    const target = e.target;
    if (!target.matches('input[type="checkbox"]')) return;

    // 1. 全選 Checkbox 觸發
    if (target.name === 'checkAll') {
        const groupName = target.dataset.target; // 如 "items1"
        const items = document.querySelectorAll(`input[name="${groupName}"]`);
        items.forEach(item => item.checked = target.checked);
        return;
    }

    // 2. 子 Checkbox 觸發 → 更新對應全選狀態
    const groupName = target.name; // 如 "items1"
    const allItems = document.querySelectorAll(`input[name="${groupName}"]`);
    const checkedItems = document.querySelectorAll(`input[name="${groupName}"]:checked`);
    const checkAll = document.querySelector(`input[name="checkAll"][data-target="${groupName}"]`);
    if (checkAll) {
        checkAll.checked = allItems.length === checkedItems.length;
        checkAll.indeterminate = checkedItems.length > 0 && checkedItems.length < allItems.length;
    }
});

進階:獲取所有選中值

function getAllCheckedValues() {
    const result = {};
    document.querySelectorAll('input[name^="items"]:checked').forEach(cb => {
        const group = cb.name;
        if (!result[group]) result[group] = [];
        result[group].push(cb.value);
    });
    return result; // { items1: ["1","3"], items2: ["2"] }
}

優勢總結

  • 零 ID 依賴:新增表格只需遵循命名規約,JS 完全復用。
  • 動態友好:AJAX 追加表格/行,無需重新綁定事件。
  • 語義清晰:indeterminate 狀態自動維護,UX 專業。
  • 框架無關:原生 JS、jQuery、Vue/React (ref + 事件委託) 皆可移植。

避坑提醒

  • 表格行包含巢狀表格時,選擇器需限定層級:table.data-table > tbody input[name="..."]。
  • 大量行(>1000)時,querySelectorAll 可能卡頓,考慮維护 Map<groupName, HTMLInputElement[]> 緩存引用。
  • 表單提交時,未勾選的 Checkbox **不會發送值**,後端需注意區分「未提交」與「提交為 false」。

用「約定優於配置」的命名規約 + 單一事件委託,輕鬆搞定任意數量表格的全選交互。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved