Next.js实现锚点链接跳转及激活状态高亮的方法
Next.js 锚点滚动与链接激活状态实现方案
前提准备
确保页面中每个需要跳转的目标区域都设置了匹配的id属性,比如链接指向#section1,对应区域就要写:
<section id="section1">...</section>
完整实现代码
在你的导航组件中添加状态管理和滚动监听逻辑,同时动态控制链接的激活样式:
'use client'; // Next.js 13+ App Router 需添加此指令,确保组件在客户端渲染 import { useState, useEffect } from 'react'; import Link from 'next/link'; import cn from 'classnames'; export default function Navbar() { // 替换成你实际的导航链接数组 const navLinks = [ { name: '首页', path: 'home' }, { name: '关于我们', path: 'about' }, { name: '服务', path: 'services' }, { name: '联系我们', path: 'contact' } ]; const [activePath, setActivePath] = useState(''); useEffect(() => { const updateActiveLink = () => { navLinks.forEach((link) => { const section = document.getElementById(link.path); if (!section) return; const rect = section.getBoundingClientRect(); // 判断元素是否进入视口(可根据需求调整阈值,这里设置为顶部距视口顶部≤100px且底部≥100px) const isActive = rect.top <= 100 && rect.bottom >= 100; if (isActive) setActivePath(link.path); }); }; // 初始加载时执行一次,设置默认激活项 updateActiveLink(); // 监听滚动事件更新激活状态 window.addEventListener('scroll', updateActiveLink); // 组件卸载时移除监听 return () => window.removeEventListener('scroll', updateActiveLink); }, [navLinks]); return ( <ul className="font-medium flex flex-col p-4 md:p-0 mt-4 md:flex-row md:space-x-8 rtl:space-x-reverse md:mt-0 transition-all"> {navLinks.map((link, index) => ( <li key={index}> <Link href={`#${link.path}`} scroll={false} // 关闭Next.js默认滚动,改用自定义平滑滚动(可选) onClick={(e) => { e.preventDefault(); const target = document.getElementById(link.path); if (target) { target.scrollIntoView({ behavior: 'smooth', block: 'start' }); // 点击后直接设置激活状态 setActivePath(link.path); } }} className={cn( "block py-2 px-3 text-white rounded md:bg-transparent md:text-blue-700 md:p-0 dark:text-white hover:dark:text-blue-500 transition-all", // 激活状态样式:这里示例为变色+下划线,可根据需求修改 activePath === link.path && "md:text-blue-500 dark:text-blue-500 underline underline-offset-4" )} aria-current={activePath === link.path ? "page" : undefined} > {link.name} </Link> </li> ))} </ul> ); }
核心逻辑说明
- 状态管理:用
activePath记录当前处于视口内的区域ID,以此控制链接的激活样式。 - 滚动监听:通过
getBoundingClientRect()获取目标区域的位置,判断其是否进入视口,实时更新activePath。 - 平滑滚动:关闭Next.js默认滚动后,手动调用
scrollIntoView实现平滑滚动,同时点击链接时直接设置激活状态。 - 样式控制:借助
classnames工具动态拼接激活样式类,实现变色、下划线等视觉反馈。 - 可访问性:通过
aria-current属性标记当前激活的链接,提升页面的无障碍体验。
如果不需要自定义平滑滚动,也可以保留Next.js默认的scroll={true},只需移除onClick里的自定义滚动逻辑即可。
内容的提问来源于stack exchange,提问作者Safeya Yasien
相关产品推荐
相关产品推荐

