如何使用Choices.js实现下拉框选中项在其他下拉框禁用?
解决Choices.js下拉框互斥选中问题
你的代码主要存在几个问题:未处理取消选择的场景、实例获取方式错误、直接修改内部存储易导致状态不同步。以下是修正后的实现方案:
核心思路
- 维护全局选中值集合,记录所有下拉框当前选中的选项
- 每个下拉框仅禁用其他下拉框已选中的选项,自身选中的选项保持可用
- 使用Choices官方API更新选项状态,避免直接操作内部存储引发异常
修正后的代码
<select class="js-choice" id="select1"> <option value="q1">问题1</option> <option value="q2">问题2</option> <option value="q3">问题3</option> </select> <select class="js-choice" id="select2"> <option value="q1">问题1</option> <option value="q2">问题2</option> <option value="q3">问题3</option> </select> <select class="js-choice" id="select3"> <option value="q1">问题1</option> <option value="q2">问题2</option> <option value="q3">问题3</option> </select> <script src="https://cdn.jsdelivr.net/npm/choices.js/public/assets/scripts/choices.min.js"></script> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/choices.js/public/assets/styles/choices.min.css"> <script> // 存储所有Choices实例,用下拉框ID作为标识 const choiceInstances = {}; // 记录每个下拉框的选中值 const selectedValues = {}; // 初始化所有下拉框 document.querySelectorAll('.js-choice').forEach(element => { const instance = new Choices(element, { shouldSort: false, searchEnabled: false, placeholder: true, placeholderValue: 'Select a Question', allowHTML: true, duplicateItemsAllowed: false, itemSelectText: 'Click to select' }); choiceInstances[element.id] = instance; // 监听选中变化事件 element.addEventListener('change', () => { // 获取当前选中值(单选场景取第一个,无选中则为null) const currentValue = instance.getValue(true)[0] || null; // 更新全局选中记录 selectedValues[element.id] = currentValue; // 同步所有下拉框的选项禁用状态 updateDisabledChoices(); }); }); // 更新所有下拉框的选项禁用状态 function updateDisabledChoices() { Object.keys(choiceInstances).forEach(id => { const instance = choiceInstances[id]; const currentSelected = selectedValues[id]; // 获取当前下拉框所有选项的value const allChoiceValues = instance._store.getStore().choices.map(c => c.value); // 先启用所有选项,避免残留禁用状态 instance.enableItems(allChoiceValues); // 收集其他下拉框已选中的有效值 const otherSelected = Object.values(selectedValues).filter(val => val !== null && val !== currentSelected); // 禁用其他下拉框已选中的选项 if (otherSelected.length > 0) { instance.disableItems(otherSelected); } }); } </script>
关键改进说明
- 支持取消选择:用户取消选中时,会将对应下拉框的选中值设为null,同步更新全局状态
- 实例管理更可靠:初始化时将实例存入对象,通过ID直接获取,避免依赖Choices内部的
instances结构 - 使用官方API操作状态:通过
enableItems和disableItems方法修改选项状态,确保UI与内部状态同步 - 保留自身修改权限:每个下拉框不会禁用自己当前选中的选项,方便用户随时修改选择
内容的提问来源于stack exchange,提问作者jane
相关产品推荐
相关产品推荐

