实现侧边导航单选激活效果:JavaScript与CSS实践

心靈之曲
发布: 2025-08-20 22:42:02
原创
411人浏览过

实现侧边导航单选激活效果:JavaScript与CSS实践

本教程旨在解决侧边导航菜单中多项同时激活显示边框的问题。通过JavaScript动态管理CSS类,确保在点击任一菜单项时,仅当前被选中的菜单项显示红色激活边框,而其他所有菜单项的激活状态被清除,从而实现单一选中效果,提升用户体验。

侧边导航基础结构

在构建交互式侧边导航时,我们通常会使用html来定义菜单结构,css来美化其外观和定义激活状态,以及javascript来处理用户交互逻辑。

HTML 结构

以下HTML代码展示了一个典型的侧边导航菜单结构,其中包含多个 main_list_item 元素,每个元素代表一个主菜单项。

<html>
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <title>side nav</title>
</head>
<body>
  <nav id="nav_menu_query_off">
    <menu id="main_menu">
      <li class="main_list_item">
        <div class="menu_header">menu one</div>
        <div class="menu_body">
          <menu class="sub_menu"></menu>
          <menu class="sub_menu"></menu>
          <menu class="sub_menu"></menu>
        </div>
      </li>
      <li class="main_list_item">
        <div class="menu_header">menu two</div>
        <div class="menu_body">
          <menu class="sub_menu"></menu>
          <menu class="sub_menu"></menu>
          <menu class="sub_menu"></menu>
        </div>
      </li>
      <li class="main_list_item">
        <div class="menu_header">menu three</div>
        <div class="menu_body">
          <menu class="sub_menu"></menu>
          <menu class="sub_menu"></menu>
          <menu class="sub_menu"></menu>
        </div>
      </li>
      <li class="main_list_item">
        <div class="menu_header">menu four</div>
        <div class="menu_body">
          <menu class="sub_menu"></menu>
          <menu class="sub_menu"></menu>
          <menu class="sub_menu"></menu>
        </div>
      </li>
    </menu>
  </nav>
</body>
</html>
登录后复制

CSS 样式

CSS用于定义导航的布局和视觉样式。其中,.active 类是实现激活效果的关键,它为菜单项底部添加了一个红色的边框。

立即学习Java免费学习笔记(深入)”;

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  text-decoration: none;
  list-style: none;
}

body {
  font-family: 'Ebrima';
  background-color: #444444;
}

nav#nav_menu_query_off {
  position: fixed;
  top: 0;
  left: 0;
  width: 200px;
  height: 100vh;
  background-color: #222222;
  overflow: auto;
  z-index: 2;
  padding: 20px 0 20px 20px;
}

nav#nav_menu_query_off menu#main_menu li.main_list_item div.menu_header {
  text-transform: uppercase;
  padding-bottom: 10px;
}

nav#nav_menu_query_off menu li {
  color: #f0f0f0;
}

nav#nav_menu_query_off menu#main_menu li.main_list_item:not(:first-child) {
  padding-top: 20px;
}

.active {
  border-bottom: 1px solid red;
}

nav::-webkit-scrollbar {
  display: none;
}
登录后复制

原始JavaScript逻辑分析

最初的JavaScript代码旨在为每个菜单项添加点击事件监听器,并在点击时切换其 active 类。

const cards = document.querySelectorAll('.main_list_item');
cards.forEach((card) => {
  const num_btn = card.querySelector('.menu_header')
  num_btn.addEventListener('click', () => {
    if (!card.classList.contains('active')) {
      card.classList.add('active');
    } else {
      card.classList.remove('active');
    }
  })
})
登录后复制

这段代码的问题在于,当一个菜单项被点击时,它只会根据自身当前是否含有 active 类来决定是添加还是移除该类。它并不会检查或修改其他菜单项的状态。这意味着,如果用户连续点击不同的菜单项,每个被点击的菜单项都会被赋予 active 类,从而导致多个菜单项同时显示红色边框,这与我们期望的“单选”效果不符。

实现单选激活的解决方案

要实现一次只有一个菜单项被激活的效果,核心思想是在激活当前菜单项之前,首先清除所有其他菜单项的激活状态。这可以通过在添加 active 类之前,遍历所有菜单项并移除它们的 active 类来实现。

火龙果写作
火龙果写作

用火龙果,轻松写作,通过校对、改写、扩展等功能实现高质量内容生产。

火龙果写作 106
查看详情 火龙果写作

以下是修改后的JavaScript代码:

const cards = document.querySelectorAll('.main_list_item');
cards.forEach((card) => {
  const num_btn = card.querySelector('.menu_header')
  num_btn.addEventListener('click', () => {
    if (!card.classList.contains('active')) {
      // 在添加当前项的active类之前,先清除所有项的active类
      cards.forEach((item) => item.classList.remove('active'));
      card.classList.add('active');
    } else {
      // 如果当前项已激活且再次点击,则移除active类(取消激活)
      card.classList.remove('active');
    }
  })
})
登录后复制

代码解析:

  1. const cards = document.querySelectorAll('.main_list_item');: 这一行获取了所有具有 main_list_item 类的DOM元素,即所有的主菜单项。
  2. cards.forEach((card) => { ... });: 为每个菜单项添加一个点击事件监听器。
  3. num_btn.addEventListener('click', () => { ... });: 当 menu_header (菜单项的标题部分)被点击时触发回调函数。
  4. if (!card.classList.contains('active')) { ... }: 判断当前点击的菜单项是否已经处于激活状态。
    • 如果包含 active 类(即未激活):
      • cards.forEach((item) => item.classList.remove('active'));: 这是关键的修改点。 它再次遍历所有的 main_list_item 元素,并强制移除它们身上的 active 类。这确保了在新的菜单项被激活之前,所有旧的激活状态都被清除。
      • card.classList.add('active');: 然后,将 active 类添加到当前被点击的菜单项上,使其显示红色边框。
    • else { card.classList.remove('active'); }: 如果当前项已经包含 active 类(即已激活),再次点击时则移除 active 类,实现取消激活的效果。

完整代码示例

为了方便理解和实践,以下是包含HTML、CSS和修正后JavaScript的完整代码:

HTML (index.html)

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <title>side nav</title>
  <link rel="stylesheet" href="style.css"> <!-- 引入CSS文件 -->
</head>
<body>
  <nav id="nav_menu_query_off">
    <menu id="main_menu">
      <li class="main_list_item">
        <div class="menu_header">menu one</div>
        <div class="menu_body">
          <menu class="sub_menu"></menu>
          <menu class="sub_menu"></menu>
          <menu class="sub_menu"></menu>
        </div>
      </li>
      <li class="main_list_item">
        <div class="menu_header">menu two</div>
        <div class="menu_body">
          <menu class="sub_menu"></menu>
          <menu class="sub_menu"></menu>
          <menu class="sub_menu"></menu>
        </div>
      </li>
      <li class="main_list_item">
        <div class="menu_header">menu three</div>
        <div class="menu_body">
          <menu class="sub_menu"></menu>
          <menu class="sub_menu"></menu>
          <menu class="sub_menu"></menu>
        </div>
      </li>
      <li class="main_list_item">
        <div class="menu_header">menu four</div>
        <div class="menu_body">
          <menu class="sub_menu"></menu>
          <menu class="sub_menu"></menu>
          <menu class="sub_menu"></menu>
        </div>
      </li>
    </menu>
  </nav>
  <script src="script.js"></script> <!-- 引入JavaScript文件 -->
</body>
</html>
登录后复制

CSS (style.css)

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  text-decoration: none;
  list-style: none;
}

body {
  font-family: 'Ebrima';
  background-color: #444444;
}

nav#nav_menu_query_off {
  position: fixed;
  top: 0;
  left: 0;
  width: 200px;
  height: 100vh;
  background-color: #222222;
  overflow: auto;
  z-index: 2;
  padding: 20px 0 20px 20px;
}

nav#nav_menu_query_off menu#main_menu li.main_list_item div.menu_header {
  text-transform: uppercase;
  padding-bottom: 10px;
  cursor: pointer; /* 添加光标指示可点击 */
}

nav#nav_menu_query_off menu li {
  color: #f0f0f0;
}

nav#nav_menu_query_off menu#main_menu li.main_list_item:not(:first-child) {
  padding-top: 20px;
}

.active {
  border-bottom: 1px solid red;
}

nav::-webkit-scrollbar {
  display: none;
}
登录后复制

JavaScript (script.js)

const cards = document.querySelectorAll('.main_list_item');
cards.forEach((card) => {
  const num_btn = card.querySelector('.menu_header')
  num_btn.addEventListener('click', () => {
    if (!card.classList.contains('active')) {
      // 在添加当前项的active类之前,先清除所有项的active类
      cards.forEach((item) => item.classList.remove('active'));
      card.classList.add('active');
    } else {
      // 如果当前项已激活且再次点击,则移除active类(取消激活)
      card.classList.remove('active');
    }
  })
})
登录后复制

注意事项与优化

  • 性能考量: 对于包含大量菜单项的复杂导航,每次点击都遍历所有元素并移除类可能会带来轻微的性能开销。但在大多数常见的侧边导航场景中(几十个或几百个菜单项),这种开销通常可以忽略不计。
  • 事件委托: 对于动态生成或数量庞大的列表项,使用事件委托可以进一步优化性能。即只在父元素上添加一个事件监听器,通过事件冒泡来判断是哪个子元素被点击。但这会使JavaScript逻辑稍微复杂一些。
  • 可维护性: 通过CSS类来管理元素的激活状态是一种推荐的做法,它将样式和行为分离,使代码更易于理解和维护。
  • 用户体验: 确保点击区域足够大,并提供视觉反馈(如 cursor: pointer)以提升用户体验。

总结

本教程详细介绍了如何通过修改JavaScript逻辑,实现侧边导航菜单的单选激活效果。核心在于利用 querySelectorAll 获取所有菜单项,并在每次点击激活新项之前,迭代清除所有旧的激活状态。这种模式广泛应用于各种UI组件,确保了界面的清晰性和用户操作的预期性。通过简单的几行代码修改,我们成功地将多选行为修正为符合用户习惯的单选行为。

以上就是实现侧边导航单选激活效果:JavaScript与CSS实践的详细内容,更多请关注php中文网其它相关文章!

Windows激活工具
Windows激活工具

Windows激活工具是正版认证的激活工具,永久激活,一键解决windows许可证即将过期。可激活win7系统、win8.1系统、win10系统、win11系统。下载后先看完视频激活教程,再进行操作,100%激活成功。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
热门推荐
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号