You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

点击无序列表项添加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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 01:22:43