You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

请求提供带复选框的级联下拉选择组件示例代码

解决方案:自定义联动下拉复选框组件

根据你的需求,我整理了一个完整的实现示例,包含自定义下拉结构、样式和交互逻辑,完全满足「点击主选项仅展开自身子复选框、选中子选项联动显示」的要求:

需求示意图说明

  • 初始状态:下拉框显示默认提示文本,下方列出所有主选项分组(如「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>

关键逻辑说明

  1. 自定义下拉结构:用div模拟下拉框,避开原生select的功能限制,实现更灵活的交互效果
  2. 分组展开控制:点击分组标题时,通过active类单独控制当前分组子选项的显示/隐藏,同时自动关闭其他分组的展开状态
  3. 选中联动:实时监听复选框的change事件,收集所有选中的子选项内容,动态更新下拉框顶部的显示文本
  4. 外部点击收起:点击页面其他区域时,自动收起下拉框和所有展开的子选项,提升整体交互体验

内容的提问来源于stack exchange,提问作者kranti

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 03:28:31