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

如何实现仅在用户滚动时显示React/Next.js导航栏

实现滚动时显示导航栏的方案

你的需求是让导航栏仅在用户滚动页面时显示,目前代码只是给中间导航项添加了固定定位类,没有控制整个导航栏的显示状态。下面是调整后的实现方案:

核心思路

  1. 新增状态控制导航栏的显示/隐藏
  2. 监听滚动事件,根据滚动距离切换显示状态
  3. 添加过渡动画让显示/隐藏更流畅
  4. 优化滚动事件触发频率,避免性能问题

修改后的完整代码

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 19:55:35