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

jQuery 遞歸級聯選中邏輯深度解析:樹形多選框全選/反選實現

     編輯:程式設計疑難解答

代碼功能概覽

實現一個多級分類樹形結構的 父子級聯選中:

  • 點擊父節點 → 所有子孫節點同步選中/取消。
  • 子節點變化 → 父節點自動判斷:全選則勾選,否則取消勾選。
  • 支持無限級巢狀 <ul><li> 結構。

HTML 結構要求

<ul class="categories">
  <li><input type="checkbox" />數碼電子
    <ul>
      <li><input type="checkbox" />手機</li>
      <li><input type="checkbox" />電腦</li>
    </ul>
  </li>
  <li><input type="checkbox" />服裝
    <ul>...</ul>
  </li>
</ul>

關鍵:input 與子 ul 為**同層相鄰元素**,.next() 可精準獲取子列表。

核心邏輯逐行解析

$("ul.categories input").click(function() {
    // 1. 獲取當前點擊 checkbox 的「直接子列表 ul」
    var children = $(this).next(); 
    
    // 2. 當前 checkbox 狀態
    var isChecked = $(this).prop("checked");

    // 3. 向下級聯:操作所有子孫 checkbox
    if (children.length) {
        if (isChecked) {
            children.find("input").prop("checked", true);   // 全選
        } else {
            children.find("input").prop("checked", false);  // 全取消
        }
    }

    // 4. 向上級聯:檢查「同級組」是否全選,決定父 checkbox 狀態
    var $parentUl = $(this).parent().parent(); // 最近的祖先 ul
    var checkedCount = $parentUl.find("> li > input:checked").length; // 同級被選數
    var totalCount   = $parentUl.find("> li > input").length;         // 同級總數

    var $parentCheckbox = $parentUl.parent().find("> input"); // 父 li 的直接 checkbox
    
    if (checkedCount === totalCount) {
        $parentCheckbox.prop("checked", true);   // 同級全選 → 父選中
    } else {
        $parentCheckbox.prop("checked", false);  // 否則父取消
    }
});

關鍵 DOM 遍歷關係圖解

<li>                          <-- $(this).parent().parent().parent()
  <input> (父)                <-- $parentCheckbox
  <ul>                        <-- $parentUl
    <li>                      <-- $(this).parent()
      <input> (當前點擊)      <-- $(this)
      <ul>                    <-- children = $(this).next()
        <li><input>...</li>  <-- children.find("input")
    </li>
  </ul>
</li>

易錯點與優化

問題原因修正
removeProp("checked") 報錯jQuery 1.6+ removeProp 刪除屬性導致無法再勾選統一用 .prop("checked", false)
多次點擊觸發重複遞歸父 checkbox 變化又觸發 click 事件用 change 事件 + 判斷 event.originalEvent 區分用戶/代碼觸發
動態添加節點無效事件綁定在現有元素用事件委託 $(document).on('change', 'ul.categories input', fn)

現代重寫(Vanilla JS / Vue / React 思路)

  • 數據驅動:維護樹形數據模型 {id, label, checked, children: []}。
  • 遞歸函數 setChecked(node, val) 處理向下,updateParent(node) 向上冒泡計算。
  • UI 僅渲染數據,邏輯與視圖解耦,易測試、擴展。

總結

這段 jQuery 代碼利用 .next()、.parent()、.find() 精準操作 DOM 樹,實現了雙向級聯。理解「同層相鄰」與「祖先後代」關係是閱讀此類代碼的關鍵。實際項目建議遷移至數據驅動框架。

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