
本文讲解如何在下拉菜单中为当前选中的选项添加 ✓ 标记,并自动移除其他选项的标记,确保始终仅有一个激活项显示勾选,支持默认选中首项及点击切换。
要实现“仅一个选项带 ✓、点击切换、默认首项已选中”的交互效果,关键在于统一管理所有选项的 checked 状态,而非为每个 单独绑定重复逻辑。原始代码存在多个问题:事件监听器未正确绑定到链接、event.target.classList.add('checked').innerText 语法错误、且未初始化默认选中状态。
以下是优化后的完整解决方案:
✅ 正确实现步骤
- 初始化时默认为首个选项添加 .checked 类
- 为所有下拉选项统一绑定点击事件,点击时清除全部 .checked,再为当前项添加
- 同步更新按钮文本(dropbtnCity)为所选项内容
- 确保 CSS 中 .checked::after 能正确渲染 ✓
✅ 修复后的 JavaScript(推荐写法)
function dropdownCity() {
document.getElementById("myDropdownCity").classList.toggle("showCity");
}
// 初始化:默认为第一个选项添加 checked
document.addEventListener('DOMContentLoaded', () => {
const firstLink = document.querySelector('#myDropdownCity a');
if (firstLink) {
firstLink.classList.add('checked');
document.querySelector('.dropbtnCity').textContent = firstLink.textContent;
}
});
// 全局点击处理(委托更优,避免重复绑定)
document.addEventListener('click', function(event) {
const target = event.target;
if (target.matches('#myDropdownCity a')) {
event.preventDefault(); // 防止跳转锚点
// 关闭下拉框
document.getElementById("myDropdownCity").classList.remove("showCity");
// 更新按钮文本
const btn = document.querySelector('.dropbtnCity');
btn.textContent = target.textContent;
// 清除所有 .checked,仅给当前项添加
const allLinks = document.querySelectorAll('#myDropdownCity a');
allLinks.forEach(link => link.classList.remove('checked'));
target.classList.add('checked');
}
});✅ 必要的 CSS 补充(确保 ✓ 显示正常)
.checked::after {
content: "✓";
margin-left: 8px; /* 推荐使用 margin-left 而非 flex 布局,避免干扰原有 display */
color: #2E7D32;
font-weight: bold;
}
/* 移除原 .checked::after 中 display:flex / justify-content 等无效属性(伪元素不支持 flex) */⚠️ 注意事项
- ❌ 不要在 window.addEventListener('click') 内部再次为每个 用 forEach + addEventListener 绑定事件——会导致多次重复监听,引发性能与逻辑问题;
- ✅ 使用事件委托(监听父容器或 document)更高效、更健壮;
- ✅ DOMContentLoaded 确保 DOM 加载完成后再初始化默认状态;
- ✅ event.preventDefault() 避免 href="#myDropdownCity" 触发页面跳转;
- ✅ 使用 textContent 替代 innerText(更标准、兼容性更好)。
通过以上实现,下拉菜单将具备专业级单选行为:首次加载即高亮首项,点击任一选项后 ✓ 自动迁移,按钮文字实时同步,逻辑清晰、无冗余、可维护性强。










