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

Gatsbyjs自定义导航栏移动端点击链接后菜单不收起问题求解

核心修改点

你只需对现有代码做3处调整即可解决问题:

  • 修复汉堡按钮的点击事件绑定错误:原代码在渲染时就直接执行了菜单切换函数,改为传递函数引用即可实现点击触发
  • 给所有导航链接添加点击回调,点击时直接将菜单展开状态设为关闭
  • 优化滚动监听事件的绑定逻辑,避免重复绑定事件

完整修改后代码

import React, { useState, useEffect, useRef } from "react";
import styled from "styled-components";
import { Link } from "gatsby";

const Navigation = styled.nav`
  display: flex;
  position: sticky;
  position: -webkit-sticky;
  position: -moz-sticky;
  position: -ms-sticky;
  position: -o-sticky;
  background-color: var(--white);
  justify-content: space-between;
  text-transform: uppercase;
  border-bottom: 2px solid var(--light-green-shadow);
  width: 100%;
  margin: 0;
  top: 0;
  padding: 0.5rem 0;
  z-index: 2;
  align-items: center;
  box-sizing: border-box;
  transition: background ease-out 300ms;
  background: ${({ background }) => background ? `var(--light-green-tint)` : `var(--light-green)`};

  @media (max-width: 768px) {
    height: 5vh;
    position: sticky;
    top: 0;
    left: 0;
    right: 0;
    left: 0;
  }
`

const Toggle = styled.div`
  display: none;
  height: 100%;
  cursor: pointer;
  padding: 0 10vw;

  @media (max-width: 768px) {
    display: flex;
  }
`

const Navbox = styled.div`
  display: flex;
  height: 100%;
  justify-content: flex-end;
  align-items: center;
  box-sizing: border-box;
  
  ul {
        display: flex;
        align-items: center;
        width: 100;
        justify-content: end;
        gap: 2rem;
        padding: 0 1rem;
        flex-direction: row;
        li {
            list-style: none;
            transition: transform 500ms;
            :hover {
                transform: translateY(-10px);

            }
            a {
                text-decoration: none;
                transition: color 300ms, transform 500ms;
                color: var(--white);
                :hover {
                    color: var(--light-grey);
                } 
            }
        }
    }

  @media (max-width: 768px) {
    flex-direction: column;
    position: fixed;
    width: 100%;
    justify-content: flex-start;
    padding-top: 10vh;
    background-color: var(--black);
    transition: all 0.3s ease-in;
    top: 6.5vh;
    right: ${({open}) => open ? "0" : "-100%"};
    ul {
        flex-direction: column;
    }
  }
`

const LogoStyle = styled.div`
    margin-left: 2.5rem;
    a {
        text-decoration: none;
        white-space: nowrap; 
        font-size: 1.65rem;
        @media (min-width: 768px) {
            white-space: nowrap;
        }
    }
`;

const Hamburger = styled.div`
  background-color: #111;
  width: 30px;
  height: 3px;
  transition: all .3s linear;
  align-self: center;
  position: relative;
  transform: ${({open}) => open ? "rotate(-45deg)" : "inherit"};

  ::before,
  ::after {
    width: 30px;
    height: 3px;
    background-color: #111;
    content: "";
    position: absolute;
    transition: all 0.3s linear;
  }

  ::before {
    transform: ${({open}) => open ? "rotate(-90deg) translate(-10px, 0px)" : "rotate(0deg)"};
    top: -10px;
  }

  ::after {
    opacity: ${({open}) => open ? "0" : "1"};
    transform: ${({open}) => open ? "rotate(90deg) " : "rotate(0deg)"};
    top: 10px;
  }
`
const Navbar = () => {
  const [navbarOpen, setNavbarOpen] = useState(false);
  const [background, setBackground] = useState(false);
    
  const changeBackground = () => {
      if (window.scrollY > 25) {
          setBackground(true);
      } else {
          setBackground(false);
      }
  }

  const toggleNavbar = () => setNavbarOpen(open => !open);
  // 新增关闭菜单方法
  const closeNavbar = () => setNavbarOpen(false);

  useEffect(() => {
      window.addEventListener('scroll', changeBackground);
      return () => {
          window.removeEventListener('scroll', changeBackground)
      }
  // 移除错误依赖避免重复绑定事件
  },[]);


  return (
    <Navigation background={background}>
       <LogoStyle> 
          <Link to="/" onClick={closeNavbar}>Performant Web Design</Link>
        </LogoStyle>
      {/* 修复点击事件绑定 */}
      <Toggle onClick={toggleNavbar}>
      <Hamburger open={navbarOpen} />
      </Toggle>
      <Navbox open={navbarOpen}>
        <ul>
            <li>
              <Link to='/services' onClick={closeNavbar}>services</Link>
            </li>
            <li>
                <Link to="/about" onClick={closeNavbar}>About</Link>
            </li>
            <li>
                <Link to="/contact" onClick={closeNavbar}>Contact</Link>
            </li>
        </ul>
      </Navbox>
    </Navigation>
  )
}

export default Navbar

内容的提问来源于stack exchange,提问作者Kelvin Nunez

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 23:54:02