点击无序列表项添加active类切换背景,解决跳转与类切换冲突
解决点击列表项时类切换与页面跳转的冲突问题
问题背景
需求:点击无序列表(ul)的列表项(li)时,为当前点击项添加active类以改变背景色,同时移除其他列表项的active类。
冲突现象:
- 添加
e.preventDefault()后,类切换功能正常,但页面无法跳转到指定链接; - 移除该语句后,页面可正常跳转,但类切换功能失效。
现有代码示例
HTML
<div id="user-account-menu"> <ul class="side-nav"> <li class=""> <a href="/me"> Settings <img class="navItems-icons" src="img/icons/settings.png" alt="settings"> </a> </li> <li class="active"> <a href="/create-user"> Create User <img class="navItems-icons" src="img/icons/create-user.png" alt="create-user"> </a> </li> </ul> </div>
CSS
li:hover:not(.active) { background-color: rgb(91, 19, 114); border-radius: 2vh; } .active { background-color: rgb(132, 2, 175); }
原JavaScript
var links = document.querySelectorAll('li'); links.forEach(function(element) { element.addEventListener('click', function(e) { // PreventDefault to prevent redirect e.preventDefault(); links.forEach(async function(element) { // element.preventDefault() await element.classList.remove('active'); }); this.classList.add('active'); }); });
问题原因
点击包含<a>标签的li时,浏览器会立即触发<a>的默认跳转行为,页面刷新会直接覆盖JS刚执行的类切换操作,导致类切换失效;而e.preventDefault()会阻止跳转,类切换能生效,但失去了页面跳转的核心功能。另外,原代码中使用async/await完全多余,classList.remove是同步操作,不需要异步处理。
解决方案
方案一:先执行类切换,再手动触发跳转
适合单页应用或需要立即看到类切换效果再跳转的场景,不需要阻止默认行为,而是先完成类操作,再通过JS手动触发页面跳转。
修改后的JavaScript:
var links = document.querySelectorAll('li'); links.forEach(function(element) { element.addEventListener('click', function() { // 移除所有li的active类 links.forEach(function(el) { el.classList.remove('active'); }); // 给当前点击的li添加active类 this.classList.add('active'); // 获取当前li内的a标签,手动跳转 const targetLink = this.querySelector('a'); if (targetLink) { window.location.href = targetLink.href; } }); });
方案二:页面加载时根据URL自动设置active类(多页应用首选)
传统多页应用跳转后会刷新页面,点击时的类切换会被刷新覆盖,因此更可靠的做法是页面加载完成后,根据当前URL匹配对应的列表项,自动添加active类,点击事件无需额外处理,让浏览器默认跳转即可。
修改后的JavaScript:
document.addEventListener('DOMContentLoaded', function() { const listItems = document.querySelectorAll('li'); const currentPagePath = window.location.pathname; listItems.forEach(function(item) { const link = item.querySelector('a'); // 匹配当前页面URL与a标签的路径 if (link && link.pathname === currentPagePath) { item.classList.add('active'); } }); });
这种方式下,点击列表项时不需要任何额外的类切换逻辑,浏览器正常跳转后,新页面加载时会自动识别当前页面并设置active类,体验更稳定。
内容的提问来源于stack exchange,提问作者user19238024
相关产品推荐
相关产品推荐

