请求提供带复选框的级联下拉选择组件示例代码
解决方案:自定义联动下拉复选框组件
根据你的需求,我整理了一个完整的实现示例,包含自定义下拉结构、样式和交互逻辑,完全满足「点击主选项仅展开自身子复选框、选中子选项联动显示」的要求:
需求示意图说明
- 初始状态:下拉框显示默认提示文本,下方列出所有主选项分组(如「Group 1」「Group 2」)
- 点击某主选项分组标题时,仅在该分组区域内展开带复选框的子选项,其他分组保持收起状态
- 勾选子选项后,下拉框顶部会实时显示已选中的子选项内容;取消勾选则自动移除对应内容
完整示例代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>联动下拉复选框</title> <style> /* 核心样式,替代你提到的multiple-select.css */ .dropdown-container { width: 300px; margin: 20px; position: relative; font-family: Arial, sans-serif; } .dropdown-main { padding: 10px; border: 1px solid #ccc; border-radius: 4px; cursor: pointer; background-color: #fff; display: flex; align-items: center; justify-content: space-between; } .dropdown-main .selected-text { flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .dropdown-main .arrow { width: 0; height: 0; border-left: 5px solid transparent; border-right: 5px solid transparent; border-top: 5px solid #666; transition: transform 0.2s; } .dropdown-main.open .arrow { transform: rotate(180deg); } .dropdown-options { position: absolute; top: 100%; left: 0; right: 0; border: 1px solid #ccc; border-top: none; border-radius: 0 0 4px 4px; background-color: #fff; max-height: 300px; overflow-y: auto; display: none; z-index: 100; } .dropdown-options.open { display: block; } .option-group { border-bottom: 1px solid #eee; } .group-title { padding: 8px 10px; background-color: #f5f5f5; cursor: pointer; font-weight: bold; } .group-title:hover { background-color: #e9e9e9; } .sub-options { display: none; padding: 5px 0; } .sub-options.active { display: block; } .sub-option { display: flex; align-items: center; padding: 6px 15px; cursor: pointer; } .sub-option:hover { background-color: #f0f0f0; } .sub-option input[type="checkbox"] { margin-right: 8px; } </style> </head> <body> <div class="dropdown-container"> <div class="dropdown-main"> <span class="selected-text">请选择选项</span> <span class="arrow"></span> </div> <div class="dropdown-options"> <!-- 分组1 --> <div class="option-group"> <div class="group-title">Group 1</div> <div class="sub-options"> <div class="sub-option"> <input type="checkbox" id="opt1-1" value="Option 1-1"> <label for="opt1-1">Option 1-1</label> </div> <div class="sub-option"> <input type="checkbox" id="opt1-2" value="Option 1-2"> <label for="opt1-2">Option 1-2</label> </div> <div class="sub-option"> <input type="checkbox" id="opt1-3" value="Option 1-3"> <label for="opt1-3">Option 1-3</label> </div> </div> </div> <!-- 分组2 --> <div class="option-group"> <div class="group-title">Group 2</div> <div class="sub-options"> <div class="sub-option"> <input type="checkbox" id="opt2-1" value="Option 2-1"> <label for="opt2-1">Option 2-1</label> </div> <div class="sub-option"> <input type="checkbox" id="opt2-2" value="Option 2-2"> <label for="opt2-2">Option 2-2</label> </div> </div> </div> </div> </div> <script> // 获取元素 const dropdownContainer = document.querySelector('.dropdown-container'); const dropdownMain = document.querySelector('.dropdown-main'); const dropdownOptions = document.querySelector('.dropdown-options'); const groupTitles = document.querySelectorAll('.group-title'); const checkboxes = document.querySelectorAll('.sub-option input[type="checkbox"]'); const selectedText = document.querySelector('.selected-text'); // 切换下拉框展开/收起 dropdownMain.addEventListener('click', () => { dropdownMain.classList.toggle('open'); dropdownOptions.classList.toggle('open'); }); // 点击分组标题,仅展开当前分组的子选项 groupTitles.forEach(title => { title.addEventListener('click', (e) => { e.stopPropagation(); // 避免触发下拉框收起 const subOptions = title.nextElementSibling; // 关闭其他分组的子选项 document.querySelectorAll('.sub-options.active').forEach(opt => { if (opt !== subOptions) opt.classList.remove('active'); }); // 切换当前分组的展开状态 subOptions.classList.toggle('active'); }); }); // 监听复选框变化,更新选中文本 checkboxes.forEach(checkbox => { checkbox.addEventListener('change', () => { const selectedValues = Array.from(checkboxes) .filter(cb => cb.checked) .map(cb => cb.value); if (selectedValues.length > 0) { selectedText.textContent = selectedValues.join(', '); } else { selectedText.textContent = '请选择选项'; } }); }); // 点击页面其他区域,收起下拉框 document.addEventListener('click', (e) => { if (!dropdownContainer.contains(e.target)) { dropdownMain.classList.remove('open'); dropdownOptions.classList.remove('open'); // 收起所有子选项 document.querySelectorAll('.sub-options.active').forEach(opt => { opt.classList.remove('active'); }); } }); </script> </body> </html>
关键逻辑说明
- 自定义下拉结构:用
div模拟下拉框,避开原生select的功能限制,实现更灵活的交互效果 - 分组展开控制:点击分组标题时,通过
active类单独控制当前分组子选项的显示/隐藏,同时自动关闭其他分组的展开状态 - 选中联动:实时监听复选框的
change事件,收集所有选中的子选项内容,动态更新下拉框顶部的显示文本 - 外部点击收起:点击页面其他区域时,自动收起下拉框和所有展开的子选项,提升整体交互体验
内容的提问来源于stack exchange,提问作者kranti
相关产品推荐
相关产品推荐

