如何实现仅在用户滚动时显示React/Next.js导航栏
实现滚动时显示导航栏的方案
你的需求是让导航栏仅在用户滚动页面时显示,目前代码只是给中间导航项添加了固定定位类,没有控制整个导航栏的显示状态。下面是调整后的实现方案:
核心思路
- 新增状态控制导航栏的显示/隐藏
- 监听滚动事件,根据滚动距离切换显示状态
- 添加过渡动画让显示/隐藏更流畅
- 优化滚动事件触发频率,避免性能问题
修改后的完整代码
import { useState, useEffect } from 'react'; import Image from 'next/image'; import Link from 'next/link'; export default function Navbar() { const [open, setOpen] = useState(false); // 控制导航栏显示状态,初始隐藏 const [isNavVisible, setIsNavVisible] = useState(false); // 记录上一次滚动位置,可选用于处理滚动方向逻辑 const [lastScrollY, setLastScrollY] = useState(0); // 简单节流函数,避免滚动事件频繁触发 const throttle = (func, delay) => { let timer = null; return (...args) => { if (!timer) { timer = setTimeout(() => { func.apply(this, args); timer = null; }, delay); } }; }; const handleScroll = () => { const currentScrollY = window.scrollY; // 自定义逻辑:滚动超过100px时显示,回到顶部则隐藏 if (currentScrollY > 100) { setIsNavVisible(true); } else { setIsNavVisible(false); } // 可选:根据滚动方向控制显示(向下滚动显示,向上滚动隐藏) // if (currentScrollY > lastScrollY && currentScrollY > 100) { // setIsNavVisible(true); // } else if (currentScrollY < lastScrollY - 50) { // setIsNavVisible(false); // } setLastScrollY(currentScrollY); }; useEffect(() => { const throttledHandleScroll = throttle(handleScroll, 100); window.addEventListener('scroll', throttledHandleScroll); return () => { window.removeEventListener('scroll', throttledHandleScroll); }; }, [lastScrollY]); return ( <> {/* 给导航栏添加固定定位与显示过渡类 */} <nav className={`fixed top-0 left-0 w-full z-50 items-center justify-between p-8 mv:hidden md:flex transition-opacity duration-300 ${isNavVisible ? 'opacity-100' : 'opacity-0 pointer-events-none'}`}> <div className='flex items-center cursor-pointer'> <Image className='w-6 h-6' src={home} alt='home icon' /> <span className='text-paragraph font-poppins ml-2 hover:text-theme transition duration-150 ease-in'>Hogwarts</span> </div> <div className='flex items-center text-paragraph w-72 justify-between font-poppins cursor-pointer'> <Link href="#projects" className='hover:text-theme transition duration-150 ease-in'>Projects</Link> <span className='hover:text-theme transition duration-150 ease-in'>About</span> <span className='hover:text-theme transition duration-150 ease-in'>Writing</span> <span className='hover:text-theme transition duration-150 ease-in'>Tools</span> </div> <button className='bg-button p-3 rounded-full text-header text-sm border border-border shadow-btn font-poppins tracking-wide'> Contact </button> </nav> <MobileButton open={open} setOpen={setOpen} /> <MobileMenu open={open} setOpen={setOpen} /> </> ); }
关键调整说明
- 状态管理:新增
isNavVisible变量控制导航栏显示,初始设为false实现默认隐藏 - 滚动优化:用节流函数限制滚动事件触发频率,避免频繁更新状态导致页面卡顿
- 样式控制:给导航栏添加
fixed top-0 left-0 w-full z-50固定在页面顶部,通过opacity类切换显示/隐藏,pointer-events-none确保隐藏时导航栏无法被点击 - 自定义阈值:修改
currentScrollY > 100中的数值可调整导航栏显示的滚动触发点,数值越小,导航栏显示时机越早
内容的提问来源于stack exchange,提问作者maxheezy's
相关产品推荐
相关产品推荐

