多实例Multiselect Dropdown仅首个下拉框更新问题求助
问题描述
实现的多选下拉框存在异常:选择第二个或其他下拉框的选项时,仅第一个下拉框会更新,其余下拉框完全无响应。
期望效果
从第二个下拉框选择选项(如「Research Report」)时,该下拉框应与第一个一样生成对应的选中标签。
代码实现
JavaScript代码
document.addEventListener("DOMContentLoaded", function() { let fieldContainers = document.querySelectorAll(".field"); fieldContainers.forEach((fieldContainer, index) => { let checkbox = fieldContainer.querySelectorAll(`#divOptions input`); let inputCheckbox = fieldContainer.querySelector("#inputCheckbox"); let unorderedList = document.createElement("ul"); unorderedList.className = "filtertags"; for (let i = 0; i < checkbox.length; i++) { checkbox[i].addEventListener("change", function(e) { if (e.target.checked) { let liTag = `<li class="txt-16-500">${checkbox[i].value}<i class="remTag"><svg width="10" height="10" viewBox="0 0 10 10" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M10 1.00714L8.99286 0L5 3.99286L1.00714 0L0 1.00714L3.99286 5L0 8.99286L1.00714 10L5 6.00714L8.99286 10L10 8.99286L6.00714 5L10 1.00714Z" fill="#FEFEFE"/> </svg></i> </li>`; unorderedList.insertAdjacentHTML("beforeend", liTag); let remIcon = unorderedList.lastElementChild.querySelector(".remTag"); remIcon.addEventListener("click", function(ev) { ev.stopPropagation(); remIcon.parentElement.remove(); checkbox[i].checked = false; updateInputCheckboxDisplay(); }); } else { let allLi = unorderedList.querySelectorAll("li"); allLi.forEach(function(li) { if (li.innerText === checkbox[i].value) { li.remove(); } }); } updateInputCheckboxDisplay(); }); } const updateInputCheckboxDisplay = function() { inputCheckbox.style.display = unorderedList.childNodes.length > 0 ? "none" : null; }; inputCheckbox.insertAdjacentElement("beforebegin", unorderedList); }); });
HTML代码
<form> <fieldset> <div class="field"> <p class="txt-14">Status</p> <div class="custom-combobox-container"> <div class="custom-combobox" onclick="showOptions(this)"> <input type="text" placeholder="Select Status" id="inputCheckbox" readonly /> </div> <div class="options-container" id="divOptions"> <label class="txt-reg-400" for="one"> <input type="checkbox" id="one" value="All" /> All </label> <label class="txt-reg-400" for="two"> <input type="checkbox" id="two" value="Drafts" /> Drafts </label> <label class="txt-reg-400" for="three"> <input type="checkbox" id="three" value="Approved" /> Approved </label> <label class="txt-reg-400" for="four"> <input type="checkbox" id="four" value="Published" /> Published </label> <label class="txt-reg-400" for="five"> <input type="checkbox" id="five" value="Submitted" /> Submitted </label> <label class="txt-reg-400" for="six"> <input type="checkbox" id="six" value="Updated" /> Updated </label> <label class="txt-reg-400" for="seven"> <input type="checkbox" id="seven" value="Rejected" /> Rejected </label> </div> </div> </div> <div class="field"> <p class="txt-14">Document Type</p> <div class="custom-combobox-container"> <div class="custom-combobox" onclick="showOptions(this)"> <input type="text" placeholder="Select Document Type" id="inputCheckbox" readonly /> </div> <div class="options-container" id="divOptions"> <label class="txt-reg-400" for="doc1"> <input type="checkbox" id="doc1" value="Research Report" /> Research Report </label> <label class="txt-reg-400" for="doc2"> <input type="checkbox" id="doc2" value="Whitepaper" /> Whitepaper </label> </div> </div> </div> </fieldset> </form>
问题原因及修复方案
核心问题
代码中使用了重复的ID(inputCheckbox、divOptions),而DOM规范中ID必须唯一。当通过querySelector或getElementById选择元素时,只会返回第一个匹配的元素,导致后续下拉框的事件绑定全部指向第一个下拉框的元素,所以操作第二个下拉框时只有第一个有反应。
修复步骤
- 替换重复ID为类选择器:
- 将HTML中的
id="inputCheckbox"改为class="inputCheckbox" - 将
id="divOptions"改为class="divOptions"
- 将HTML中的
- 修改JavaScript中的选择器逻辑:
- 把
fieldContainer.querySelectorAll(#divOptions input)改为fieldContainer.querySelectorAll(.divOptions input) - 把
fieldContainer.querySelector("#inputCheckbox")改为fieldContainer.querySelector(".inputCheckbox")
- 把
修复后的完整代码
JavaScript代码
document.addEventListener("DOMContentLoaded", function() { let fieldContainers = document.querySelectorAll(".field"); fieldContainers.forEach((fieldContainer, index) => { // 改用类选择器获取当前field下的复选框 let checkbox = fieldContainer.querySelectorAll(`.divOptions input`); // 改用类选择器获取当前field下的输入框 let inputCheckbox = fieldContainer.querySelector(".inputCheckbox"); let unorderedList = document.createElement("ul"); unorderedList.className = "filtertags"; for (let i = 0; i < checkbox.length; i++) { checkbox[i].addEventListener("change", function(e) { if (e.target.checked) { let liTag = `<li class="txt-16-500">${checkbox[i].value}<i class="remTag"><svg width="10" height="10" viewBox="0 0 10 10" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M10 1.00714L8.99286 0L5 3.99286L1.00714 0L0 1.00714L3.99286 5L0 8.99286L1.00714 10L5 6.00714L8.99286 10L10 8.99286L6.00714 5L10 1.00714Z" fill="#FEFEFE"/> </svg></i> </li>`; unorderedList.insertAdjacentHTML("beforeend", liTag); let remIcon = unorderedList.lastElementChild.querySelector(".remTag"); remIcon.addEventListener("click", function(ev) { ev.stopPropagation(); remIcon.parentElement.remove(); checkbox[i].checked = false; updateInputCheckboxDisplay(); }); } else { let allLi = unorderedList.querySelectorAll("li"); allLi.forEach(function(li) { // 增加trim处理避免空格导致匹配失败 if (li.innerText.trim() === checkbox[i].value) { li.remove(); } }); } updateInputCheckboxDisplay(); }); } const updateInputCheckboxDisplay = function() { inputCheckbox.style.display = unorderedList.childNodes.length > 0 ? "none" : null; }; inputCheckbox.insertAdjacentElement("beforebegin", unorderedList); }); });
HTML代码
<form> <fieldset> <div class="field"> <p class="txt-14">Status</p> <div class="custom-combobox-container"> <div class="custom-combobox" onclick="showOptions(this)"> <!-- 替换id为class --> <input type="text" placeholder="Select Status" class="inputCheckbox" readonly /> </div> <!-- 替换id为class --> <div class="options-container divOptions"> <label class="txt-reg-400" for="one"> <input type="checkbox" id="one" value="All" /> All </label> <label class="txt-reg-400" for="two"> <input type="checkbox" id="two" value="Drafts" /> Drafts </label> <label class="txt-reg-400" for="three"> <input type="checkbox" id="three" value="Approved" /> Approved </label> <label class="txt-reg-400" for="four"> <input type="checkbox" id="four" value="Published" /> Published </label> <label class="txt-reg-400" for="five"> <input type="checkbox" id="five" value="Submitted" /> Submitted </label> <label class="txt-reg-400" for="six"> <input type="checkbox" id="six" value="Updated" /> Updated </label> <label class="txt-reg-400" for="seven"> <input type="checkbox" id="seven" value="Rejected" /> Rejected </label> </div> </div> </div> <div class="field"> <p class="txt-14">Document Type</p> <div class="custom-combobox-container"> <div class="custom-combobox" onclick="showOptions(this)"> <input type="text" placeholder="Select Document Type" class="inputCheckbox" readonly /> </div> <div class="options-container divOptions"> <label class="txt-reg-400" for="doc1"> <input type="checkbox" id="doc1" value="Research Report" /> Research Report </label> <label class="txt-reg-400" for="doc2"> <input type="checkbox" id="doc2" value="Whitepaper" /> Whitepaper </label> </div> </div> </div> </fieldset> </form>
额外优化建议
- 确保所有复选框的ID唯一,避免点击标签时触发错误的复选框
- 保留标签的
for属性并与对应复选框ID匹配,保证标签点击的交互正常 - 匹配标签文本与复选框值时,使用
trim()处理,避免因空格导致匹配失败
内容的提问来源于stack exchange,提问作者Harshvardhan Shete
相关产品推荐
相关产品推荐

