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
相关产品推荐
相关产品推荐

