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

如何用原生JS实现无jQuery/Bootstrap依赖的多选下拉框

原生JavaScript实现多选下拉框

多选下拉框效果截图

原生<select>标签自带的多选功能样式无法灵活定制,和参考图效果差异较大,我们可以通过隐藏原生select、生成自定义DOM结构的方式实现,全程不依赖任何第三方库,同时保留原生select的表单值同步能力。


完整实现代码

在原有HTML基础上补充如下CSS和JS代码即可:

<!-- 原有select代码,需补充multiple属性支持多选 -->
<select name="city" id="mySelect" multiple>
  <option value="banglore">Banglore</option>
  <option value="bhubaneswar">Bhubaneswar</option>
  <option value="patna">Patna</option>
  <option value="indore">Indore</option>
</select>

<style>
/* 自定义多选下拉基础样式 */
.custom-multiselect {
  position: relative;
  width: 220px;
  font-family: system-ui, sans-serif;
}
.multiselect-header {
  border: 1px solid #d0d0d0;
  padding: 8px 12px;
  border-radius: 4px;
  cursor: pointer;
  display: flex;
  justify-content: space-between;
  align-items: center;
  background: #fff;
  min-height: 20px;
  font-size: 14px;
}
.multiselect-header::after {
  content: "▼";
  font-size: 12px;
  color: #666;
}
.multiselect-options {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  border: 1px solid #d0d0d0;
  border-top: none;
  border-radius: 0 0 4px 4px;
  max-height: 220px;
  overflow-y: auto;
  background: #fff;
  z-index: 99;
  display: none;
  margin-top: 2px;
  box-shadow: 0 2px 6px rgba(0,0,0,0.1);
}
.multiselect-options.show {
  display: block;
}
.multiselect-option {
  padding: 8px 12px;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
}
.multiselect-option:hover {
  background: #f5f5f5;
}
.multiselect-option.selected {
  background: #eef4ff;
}
.multiselect-option input {
  margin: 0;
  cursor: pointer;
}
</style>

<script>
// 多选下拉初始化方法
function initMultiSelect(selectEl) {
  // 隐藏原生select
  selectEl.style.display = 'none';
  // 创建自定义下拉结构
  const container = document.createElement('div');
  container.className = 'custom-multiselect';
  const header = document.createElement('div');
  header.className = 'multiselect-header';
  header.textContent = '请选择城市';
  const optionsWrap = document.createElement('div');
  optionsWrap.className = 'multiselect-options';

  // 遍历原生option生成自定义选项
  const originOptions = selectEl.querySelectorAll('option');
  originOptions.forEach(option => {
    const optionItem = document.createElement('label');
    optionItem.className = 'multiselect-option';
    const checkbox = document.createElement('input');
    checkbox.type = 'checkbox';
    checkbox.value = option.value;
    
    // 复选框状态同步到原生select
    checkbox.addEventListener('change', () => {
      option.selected = checkbox.checked;
      optionItem.classList.toggle('selected', checkbox.checked);
      updateHeaderText();
    });

    const optionText = document.createElement('span');
    optionText.textContent = option.textContent;
    optionItem.append(checkbox, optionText);
    optionsWrap.append(optionItem);
  });

  // 更新头部已选内容显示
  function updateHeaderText() {
    const selectedTexts = Array.from(selectEl.selectedOptions).map(opt => opt.textContent);
    header.textContent = selectedTexts.length ? selectedTexts.join(', ') : '请选择城市';
  }

  // 点击头部切换下拉展开/收起
  header.addEventListener('click', (e) => {
    e.stopPropagation();
    optionsWrap.classList.toggle('show');
  });

  // 点击外部区域自动收起下拉
  document.addEventListener('click', () => {
    optionsWrap.classList.remove('show');
  });
  // 点击选项区域内部不触发收起
  optionsWrap.addEventListener('click', (e) => {
    e.stopPropagation();
  });

  // 组装DOM插入到原生select位置
  container.append(header, optionsWrap);
  selectEl.parentNode.insertBefore(container, selectEl);
}

// 页面加载完成后初始化目标下拉框
document.addEventListener('DOMContentLoaded', () => {
  const citySelect = document.getElementById('mySelect');
  initMultiSelect(citySelect);
});
</script>

实现说明

  • 必须给原生select标签添加multiple属性才能支持多选值存储,最终表单提交、JS通过原生select API获取选中值的逻辑完全不受影响,不需要额外适配
  • 点击下拉头部可展开/收起选项列表,点击选项前的复选框即可切换选中状态,选中项会有高亮背景
  • 所有选中项的文本会自动拼接显示在下拉头部,未选择时显示默认提示文字
  • 点击下拉框外部区域会自动收起选项列表,交互符合常规表单组件使用习惯

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 18:09:38