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

如何在React中使用classList?解决响应式导航栏切换报错问题

解决移动端导航栏Toggle状态异常问题

你的代码里导致classList添加"open"类失败的核心问题是事件绑定错误,还有几处CSS语法问题,下面是具体修复方案:

核心问题与修复步骤

  • 事件绑定错误:你在onClick里写的是toggleMenu(),这会让组件一渲染就立即执行函数,而不是点击时触发。必须改成传递函数引用onClick={toggleMenu}。
  • DOM查找的潜在问题:用document.querySelector在React里不是最优解,改用useRef可以更安全地获取DOM元素,避免找不到元素的情况。
  • CSS语法错误:transition属性缺少时间单位s,top:100没有单位,还有重复的CSS规则导致样式冲突。

修正后的移动端导航组件Nav2

import { useRef } from 'react';

const Nav2 = () => {
  const menuRef = useRef(null);
  const iconRef = useRef(null);

  const toggleMenu = () => {
    menuRef.current.classList.toggle("open");
    iconRef.current.classList.toggle("open");
  };

  return (
    <nav id="lined-nav">
      <div className="logo">Umar Manzoor</div>
      <div className="lined-menu">
        <div className="lined-icon" onClick={toggleMenu} ref={iconRef}>
          <span></span>
          <span></span>
          <span></span>
        </div>
        <div className="menu-links" ref={menuRef}>
          <li>
            <a href="#about" onClick={toggleMenu}>
              About
            </a>
          </li>
          <li>
            <a href="#experience" onClick={toggleMenu}>
              Experience
            </a>
          </li>
          <li>
            <a href="#projects" onClick={toggleMenu}>
              Projects
            </a>
          </li>
          <li>
            <a href="#contact" onClick={toggleMenu}>
              Contact
            </a>
          </li>
        </div>
      </div>
    </nav>
  );
};

export default Nav2;

修正后的CSS样式

/* 桌面/移动端切换基础样式 */
#desktop-nav {
  display: flex; /* 默认显示桌面导航 */
}
#lined-nav {
  display: none; /* 默认隐藏移动端导航 */
}

@media screen and (max-width: 1100px) {
  #desktop-nav {
    display: none;
  }
  #lined-nav {
    display: flex;
    justify-content: space-between; /* 让logo和菜单图标左右分布 */
    align-items: center;
    width: 100%;
    padding: 0 20px;
  }
}

/* 汉堡菜单图标样式 */
.lined-icon {
  cursor: pointer;
  padding: 10px;
}
.lined-icon span {
  display: block; /* 让span块级显示,形成三条横线 */
  width: 25px;
  height: 2px;
  background-color: black;
  margin: 5px 0;
  transition: all 0.3s ease-in-out; /* 补全单位s */
}

/* 移动端菜单链接容器 */
.menu-links {
  position: absolute;
  top: 100%; /* 补全单位%,让菜单紧贴导航栏下方 */
  right: 0;
  background-color: white;
  width: fit-content;
  max-height: 0;
  overflow: hidden;
  transition: all 0.3s ease-in-out; /* 补全单位s */
  box-shadow: 0 2px 5px rgba(0,0,0,0.1); /* 加个阴影提升视觉效果 */
}

.menu-links a {
  display: block;
  padding: 15px 20px;
  text-align: center;
  font-size: 1.5rem;
  color: black;
  text-decoration: none;
  transition: all 0.3s ease-in-out;
}

.menu-links a:hover {
  background-color: #f5f5f5; /* 鼠标悬停背景色 */
}

.menu-links li {
  list-style: none;
}

/* 菜单展开状态 */
.menu-links.open {
  max-height: 300px;
}

/* 汉堡图标展开动画 */
.lined-icon.open span:first-child {
  transform: rotate(45deg) translate(5px, 5px); /* 调整位移,避免图标偏移过大 */
}

.lined-icon.open span:nth-child(2) {
  opacity: 0;
}

.lined-icon.open span:last-child {
  transform: rotate(-45deg) translate(7px, -6px);
}

/* 图标默认状态(去掉重复规则) */
.lined-icon span:first-child {
  transform: none;
  opacity: 1;
}
.lined-icon span:nth-child(2) {
  transform: none;
  opacity: 1;
}
.lined-icon span:last-child {
  transform: none;
  opacity: 1;
}

额外说明

  • 给桌面导航默认加上display: flex,确保大屏幕下正常显示。
  • 给移动端导航添加布局样式,让logo和汉堡图标合理分布。
  • 调整了汉堡图标的位移参数,避免展开后图标位置异常。
  • 增加了链接悬停效果,提升交互体验。

内容的提问来源于stack exchange,提问作者Umar Manzoor

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 06:04:56