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

NextJS项目平滑滚动仅部分生效问题求助

NextJS平滑滚动仅部分生效的解决办法

问题背景

在NextJS作品集网站中,通过global.css设置了:

html { 
   scroll-behavior: smooth
}

但仅指向根路径/的链接(如导航栏Home、返回顶部按钮)能触发平滑滚动,而导航栏中带锚点的链接(如/#contact)直接跳转,无平滑效果。

核心原因

Next.js的<Link>组件在处理带锚点的同页面跳转时,默认的自动滚动逻辑会绕过浏览器原生的scroll-behavior: smooth设置,直接定位到锚点位置。

解决方案

方案1:单个链接手动控制滚动

给目标<Link>添加scroll={false}禁用默认滚动,然后通过onClick事件手动调用原生平滑滚动API:

<Link href="/#contact" scroll={false} onClick={() => {
  const targetElement = document.getElementById('contact');
  if (targetElement) {
    targetElement.scrollIntoView({ behavior: 'smooth' });
  }
}}>
  <li className="ml-10 text-sm uppercase hover:border-b">
    Contact
  </li>
</Link>

方案2:全局监听路由统一处理

在_app.js中使用useRouter监听路由变化,当路由包含锚点时自动触发平滑滚动,无需逐个修改链接:

import { useRouter } from 'next/router';
import { useEffect } from 'react';

export default function MyApp({ Component, pageProps }) {
  const router = useRouter();

  useEffect(() => {
    const handleRouteComplete = (url) => {
      const hash = url.split('#')[1];
      if (hash) {
        setTimeout(() => {
          const target = document.getElementById(hash);
          target?.scrollIntoView({ behavior: 'smooth' });
        }, 0);
      }
    };

    router.events.on('routeChangeComplete', handleRouteComplete);
    return () => router.events.off('routeChangeComplete', handleRouteComplete);
  }, [router]);

  return <Component {...pageProps} />;
}

方案3:检查锚点元素有效性

确保目标锚点元素的id与链接中的锚点值完全匹配(如#contact对应<section id="contact">),且元素未被display: none或其他定位属性隐藏,保证DOM能正确获取到该元素。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 22:20:32