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

基于GatsbyJS的单页网站菜单激活类名设置方法问询

如何在Gatsby单页滚动导航中给当前区块链接添加Active类

嘿,这个需求我在自己的Gatsby项目里刚实现过,给你分享两个实用的方案,都是亲测有效的:

方案一:用React原生钩子手动实现(自定义程度高)

如果想完全掌控滚动监听的逻辑,用useState+useEffect就能搞定,步骤如下:

  1. 先给页面每个区块加上对应的id,比如:
<section id="home">...</section>
<section id="about">...</section>
<section id="portfolio">...</section>
  1. 在导航组件里,通过滚动监听判断当前视口对应的区块,动态设置active类:
import React, { useState, useEffect } from 'react';

const Navbar = () => {
  // 默认激活home区块
  const [activeSection, setActiveSection] = useState('home');

  const handleScroll = () => {
    // 获取所有带id的section元素
    const sections = document.querySelectorAll('section[id]');
    
    sections.forEach(section => {
      const sectionRect = section.getBoundingClientRect();
      const sectionId = section.getAttribute('id');
      
      // 这里的100是阈值,可以根据你的固定导航栏高度调整
      // 当区块顶部距离视口顶部<=100px,且底部还没完全移出视口时,标记为active
      if (sectionRect.top <= 100 && sectionRect.bottom >= 0) {
        setActiveSection(sectionId);
      }
    });
  };

  // 组件挂载时添加滚动监听,卸载时移除
  useEffect(() => {
    window.addEventListener('scroll', handleScroll);
    return () => window.removeEventListener('scroll', handleScroll);
  }, []);

  return (
    <nav className="navbar">
      <ul>
        <li>
          <a 
            href="#home" 
            className={`nav-link ${activeSection === 'home' ? 'active' : ''}`}
            onClick={(e) => {
              e.preventDefault();
              // 平滑滚动到对应区块
              document.getElementById('home').scrollIntoView({ behavior: 'smooth' });
            }}
          >
            Home
          </a>
        </li>
        <li>
          <a 
            href="#about" 
            className={`nav-link ${activeSection === 'about' ? 'active' : ''}`}
            onClick={(e) => {
              e.preventDefault();
              document.getElementById('about').scrollIntoView({ behavior: 'smooth' });
            }}
          >
            About
          </a>
        </li>
        <li>
          <a 
            href="#portfolio" 
            className={`nav-link ${activeSection === 'portfolio' ? 'active' : ''}`}
            onClick={(e) => {
              e.preventDefault();
              document.getElementById('portfolio').scrollIntoView({ behavior: 'smooth' });
            }}
          >
            Portfolio
          </a>
        </li>
      </ul>
    </nav>
  );
};

export default Navbar;
  1. 最后在CSS里给.active类加高亮样式就行,比如:
.nav-link.active {
  color: #your-highlight-color;
  border-bottom: 2px solid #your-highlight-color;
}

方案二:用react-scroll库(省心省力)

如果不想自己写滚动逻辑,react-scroll这个库已经封装好了滚动监听和active状态管理,用起来超方便:

  1. 先安装依赖:
npm install react-scroll
# 或者用yarn
yarn add react-scroll
  1. 在导航组件里使用库提供的Link组件,它会自动识别当前滚动位置并添加active类:
import React from 'react';
import { Link } from 'react-scroll';

const Navbar = () => {
  return (
    <nav className="navbar">
      <ul>
        <li>
          <Link
            activeClass="active" // 激活时添加的类名
            to="home" // 对应区块的id
            spy={true} // 开启滚动监听
            smooth={true} // 平滑滚动
            offset={-70} // 偏移量,根据你的固定导航栏高度调整,避免被遮挡
            duration={500} // 滚动动画时长
            className="nav-link"
          >
            Home
          </Link>
        </li>
        <li>
          <Link
            activeClass="active"
            to="about"
            spy={true}
            smooth={true}
            offset={-70}
            duration={500}
            className="nav-link"
          >
            About
          </Link>
        </li>
        <li>
          <Link
            activeClass="active"
            to="portfolio"
            spy={true}
            smooth={true}
            offset={-70}
            duration={500}
            className="nav-link"
          >
            Portfolio
          </Link>
        </li>
      </ul>
    </nav>
  );
};

export default Navbar;
  1. 同样,区块的id要和Link的to属性对应上,然后给.active类加高亮样式就OK了。

小提示

  • 如果你的导航栏是固定在顶部的,一定要调整阈值(方案一的100)或者偏移量(方案二的offset),不然区块会被导航栏挡住,active状态的切换也会不准。
  • 方案一的逻辑可以根据需求自定义,比如你想让区块中间进入视口才激活,就调整判断条件里的数值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 03:43:11