如何为JS循环控制的下拉框首个选项添加清除按钮并移除对勾标记
解决方案
核心修改点
- 生成选项时判断是否为Clear清除项,是则不插入前面的复选框HTML,自然就不会显示勾选对勾
- 单独编写Clear项的点击逻辑,不走普通选项的选中/取消选中流程,直接执行全量清除操作
具体修改步骤
1. 调整选项生成逻辑
找到循环中拼接option内容的代码,新增Clear项的判断:
for (let i = 0; i < options.length; i++) { let optionDiv = document.createElement("div"); // 新增判断:如果是clear项,不拼接复选框 let currentOption = options[i]; let optionContent = currentOption.value === 'clear' ? currentOption.innerHTML : checkmark + currentOption.innerHTML; optionDiv.innerHTML = optionContent; optionDiv.classList.add("c-dropdown__option"); optionsContainer.appendChild(optionDiv); // 后续点击逻辑修改见下 }
2. 重写Clear项的点击逻辑
在多选场景的点击事件最开头新增Clear项判断,直接执行清除逻辑:
optionDiv.onclick = function (e) { if (!multiple) { // 原有单选逻辑保持不变 // ... } else { // 新增:如果是clear项,直接走清除逻辑 if (options[i].value === 'clear') { // 遍历所有选项,移除选中状态 for (let j = 0; j < options.length; j++) { options[j].removeAttribute("selected"); // 找到对应选项的复选框,设为未选中 let optCheckbox = optionsContainer.querySelectorAll(".c-dropdown__option")[j].querySelector("input"); if (optCheckbox) optCheckbox.checked = false; } // 重置顶部选中展示 container.innerHTML = labelText; container.classList.remove("c-dropdown__container--has-value"); // 关闭下拉框 container.classList.remove("c-dropdown--active"); optionsContainer.classList.remove("c-dropdown--active"); // 触发change事件后直接返回,不执行后续普通选项逻辑 dropdown.querySelector("select").dispatchEvent(new Event("change")); return; } // 原有普通多选选项的逻辑保持不变 let target = e.target.tagName; let checkbox; // ... 原有剩余逻辑 } }
完整修改后的JS代码
function dropdowns() { let dropdowns = document.querySelectorAll(".c-dropdown"); let checkboxHTML = '<label class="c-checkbox"><input type="checkbox"><span class="c-checkmark"></span></label>'; let clearButtonHTML = '<div class="dropdown-clear-option"><span class="icon-24-refresh-mono clear-icon"></span>Clear</div>'; dropdowns.forEach(function (dropdown) { (function (dropdown) { let multiple = dropdown.querySelector("select").hasAttribute("multiple"); let checkmark = multiple ? checkboxHTML : ""; let clearAll = dropdown.querySelector("select").hasAttribute("clearbtn"); if (multiple) { dropdown.classList.add("c-dropdown--multiple"); } let container = document.createElement("div"); container.setAttribute("tabindex", "0"); container.innerHTML = dropdown.classList.contains( "c-dropdown--inline-label" ) ? dropdown.querySelector("label").innerHTML : "Order Source"; container.classList.add("c-dropdown__container"); dropdown.appendChild(container); let optionsContainer = document.createElement("div"); optionsContainer.classList.add("c-dropdown__options-container"); dropdown.appendChild(optionsContainer); let options = dropdown.querySelectorAll("select option"); let labelText = dropdown.querySelector("label").innerHTML; //***** Setting up Clear button let firstOption = dropdown.querySelector("select option[value=clear]"); firstOption.innerHTML = clearButtonHTML; for (let i = 0; i < options.length; i++) { // ****** Loop adds innerHTML let optionDiv = document.createElement("div"); let currentOption = options[i]; // 新增判断:clear项不加复选框 let optionContent = currentOption.value === 'clear' ? currentOption.innerHTML : checkmark + currentOption.innerHTML; optionDiv.innerHTML = optionContent; optionDiv.classList.add("c-dropdown__option"); optionsContainer.appendChild(optionDiv); optionDiv.onclick = function (e) { if (!multiple) { dropdown.querySelector("select").selectedIndex = i; for (let j = 0; j < options.length; j++) { if (i === j) options[j].setAttribute("selected", "selected"); else options[j].removeAttribute("selected"); } container.innerHTML = options[i].innerHTML; container.classList.toggle("c-dropdown--active"); optionsContainer.classList.toggle("c-dropdown--active"); container.classList.add("c-dropdown__container--has-value"); } else { // 新增clear项点击逻辑 if (options[i].value === 'clear') { for (let j = 0; j < options.length; j++) { options[j].removeAttribute("selected"); let optEl = optionsContainer.querySelectorAll(".c-dropdown__option")[j]; let optCheckbox = optEl.querySelector("input"); if (optCheckbox) optCheckbox.checked = false; } container.innerHTML = labelText; container.classList.remove("c-dropdown__container--has-value"); container.classList.remove("c-dropdown--active"); optionsContainer.classList.remove("c-dropdown--active"); dropdown.querySelector("select").dispatchEvent(new Event("change")); return; } let target = e.target.tagName; let checkbox; switch (target) { case "DIV": //Option text checkbox = e.target.querySelector("input"); break; case "SPAN": checkbox = e.target.parentElement.querySelector("input"); e.preventDefault(); e.stopPropagation(); break; case "INPUT": //Checkbox checkbox = e.target; e.preventDefault(); e.stopPropagation(); break; } if (options[i].hasAttribute("selected")) { options[i].removeAttribute("selected"); checkbox.checked = false; } else { options[i].setAttribute("selected", "selected"); checkbox.checked = true; } let selected = []; for (let j = 0; j < options.length; j++) { if (options[j].hasAttribute("selected")) { selected.push(options[j].innerHTML); } } container.innerHTML = "Select"; let maxLength = Math.floor(container.clientWidth / 14); let string = ""; for (let k = 0; k < selected.length; k++) { string += selected[k]; if (k < selected.length - 1) { string += ", "; } } if (string.length > maxLength) { string = selected[0] + ", +" + (selected.length - 1); } if (selected.length === 0) { container.innerHTML = labelText; container.classList.remove("c-dropdown__container--has-value"); } else { container.innerHTML = string; container.classList.add("c-dropdown__container--has-value"); } } dropdown.querySelector("select").dispatchEvent(new Event("change")); }; } container.onclick = function (e) { container.classList.toggle("c-dropdown--active"); optionsContainer.classList.toggle("c-dropdown--active"); e.stopPropagation(); }; })(dropdown); }); document.onclick = function () { document .querySelectorAll( ".c-dropdown__container, .c-dropdown__options-container" ) .forEach(function (element) { element.classList.remove("c-dropdown--active"); }); }; } dropdowns();
内容的提问来源于stack exchange,提问作者iosSicilian
相关产品推荐
相关产品推荐

