如何为自定义国家码下拉框的选中选项设置背景高亮
问题解决:国家码下拉选择器选中项无法高亮
问题描述
实现的国际化国家码下拉选择器功能正常,但用户选中选项后再次打开下拉列表,已选选项无法通过CSS高亮显示。
问题根源
- 重复事件绑定:
handleDocumentClick函数内部重复给document添加点击监听器,导致下拉列表的显示/隐藏逻辑异常,影响选中项样式渲染。 - CSS优先级不足:
.selected-country类的优先级与.cc-list-items相同,可能被其他样式(如hover)覆盖,导致高亮不生效。 - DOM结构错误:按钮内部使用
<option>标签不符合HTML规范,可能引发浏览器解析异常。 - CSS拼写错误:
.cc-data-list的border属性值拼写错误(soldi应为solid),虽不影响高亮,但需修正以保证样式完整性。
修复方案
1. 修复重复事件绑定
修改handleDocumentClick函数,移除内部重复添加的监听器,直接处理点击逻辑:
function handleDocumentClick(event) { if (!formRoot.contains(event.target)) { ccContainer.classList.remove("show-cc-list"); } }
2. 提高选中项CSS优先级
使用组合选择器提升选中项样式优先级,确保高亮生效,同时添加文字颜色增强对比度:
.cc-list-items.selected-country { cursor: pointer; background-color: rgb(73, 118, 241); color: white; }
3. 修复按钮内的DOM元素
将createButtonHtml中的<option>标签替换为<span>,符合HTML规范:
function createButtonHtml(code, flag) { return ` <div class="flag-icon flag-icon-${flag}"></div> <span class="cc-code" value="+${code}">+${code}</span> `; }
4. 修正CSS拼写错误
修正.cc-data-list的border属性拼写:
.cc-data-list { /* 其他样式不变 */ border: 1px solid darkgray; }
完整修改后的代码
JavaScript
const countryData = [ { name: "Afganistan", code: "93", flag: "afg" }, { name: "Albania", code: "355", flag: "alb" }, { name: "Algeria", code: "213", flag: "dza" }, { name: "Canada", code: "1", flag: "can" }, { name: "Cape Verde", code: "238", flag: "cpv" }, { name: "Cayman Islands", code: "1-345", flag: "cym" }, { name: "United States", code: "1", flag: "usa" }, { name: "Uruguay", code: "598", flag: "ury" }, { name: "Uzbekistan", code: "998", flag: "uzb" } ]; function registerForm(formRoot) { const ccButton = formRoot.querySelector(".cc-telcode"); const ccContainer = formRoot.querySelector(".cc-container"); const ccSearchInput = formRoot.querySelector(".cc-search-box"); const ccList = formRoot.querySelector(".cc-data-list"); let selectedCountry = ""; // 以code为标识保存选中项 ccButton.addEventListener("click", handleButton); ccSearchInput.addEventListener("input", handleInput); ccList.addEventListener("click", handleListClick); document.addEventListener("click", handleDocumentClick); function handleDocumentClick(event) { if (!formRoot.contains(event.target)) { ccContainer.classList.remove("show-cc-list"); } } function handleButton() { ccContainer.classList.toggle("show-cc-list"); ccList.innerHTML = createListHtml(countryData); } function createListHtml(countryData) { return countryData.map((obj) => { const { name, code, flag } = obj; let isSelected = ""; if (obj.code == selectedCountry) isSelected = "selected-country"; return ` <li class="cc-list-items ${isSelected}" data-name="${name}" data-code="${code}" data-flag="${flag}"> <div class="flag-icon flag-icon-${flag}"></div> <div class="name">${name} (+${code})</div> </li> `; }).join(""); } function handleInput(e) { const { value } = e.target; if (value) { const filtered = filterData(countryData, value); if (filtered.length) { ccList.innerHTML = createListHtml(filtered); } else { ccList.innerHTML = createNoDataHtml(); } } else { ccList.innerHTML = createListHtml(countryData); } } function handleListClick(e) { const item = e.target.closest("li") || e.target; if (item.classList.contains("cc-list-items")) { const { code, flag } = item.dataset; selectedCountry = item.dataset.code; ccButton.innerHTML = createButtonHtml(code, flag); ccContainer.classList.remove("show-cc-list"); } } } function filterData(countryData, value) { return countryData.filter((obj) => { return ( obj.name.toLowerCase().startsWith(value.toLowerCase()) || obj.code.toLowerCase().startsWith(value.toLowerCase()) ); }); } function createButtonHtml(code, flag) { return ` <div class="flag-icon flag-icon-${flag}"></div> <span class="cc-code" value="+${code}">+${code}</span> `; } function createNoDataHtml() { return '<li class="no-data-found">Sorry, No Data Found</li>'; } const contactDiv = document.querySelector(".contact-frm-cc"); registerForm(contactDiv);
CSS
.cc-telcode { margin-bottom: 1em; display: flex; justify-content: center; width: 100%; } .cc-telcode span.cc-code, .cc-list-items div.name { margin-left: 0.25em; } .cc-container { display: none; width: 300px; position: absolute; } .show-cc-list { display: block; z-index: +999; } .cc-data-list { max-height: 100px; list-style: none; margin: 1em 0 0 0; padding: 0; overflow-y: scroll; border: 1px solid darkgray; } .cc-list-items { display: flex; padding: 0.25em; border: 1px solid lightgray; } .cc-list-items:hover { cursor: pointer; background-color: lightyellow; } .cc-list-items.selected-country { cursor: pointer; background-color: rgb(73, 118, 241); color: white; } .contact-frm-cc, .consult-frm-cc { width: 100px; }
HTML
<link href="https://amitdutta.co.in/flag/css/flag-icon.css" rel="stylesheet"/> <div class="contact-frm-cc"> <button class="cc-telcode">Tel code</button> <section class="cc-container"> <input type="text" class="cc-search-box" placeholder="Search for country" /> <ul class="cc-data-list"> </ul> </section> </div>
效果说明
修改后,用户选中国家码选项后,再次打开下拉列表时,已选选项会通过蓝色背景搭配白色文字高亮显示,符合预期需求。
内容的提问来源于stack exchange,提问作者Gupa Dutta
相关产品推荐
相关产品推荐

