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

Next.js原生平滑滚动实现问题求助

不依赖Edge浏览器设置的平滑滚动实现方案

核心思路

Edge浏览器的平滑滚动flag会干扰原生scroll-behavior: smooth和部分第三方库的行为,因此需要完全通过JavaScript手动控制滚动过程,绕过浏览器的原生滚动机制,确保效果一致且不依赖用户设置。

方案一:纯原生JS自定义平滑滚动函数

通过requestAnimationFrame逐帧计算滚动位置,完全自主控制滚动速度和缓动效果,不受任何浏览器设置影响。

实现代码

// 自定义平滑滚动函数,支持目标元素或目标位置,可自定义时长
function smoothScrollTo(target, duration = 500) {
  const startScrollY = window.scrollY;
  // 计算目标位置:如果传入的是元素,获取其相对于视口的位置加上当前滚动距离;如果是数字则直接使用
  const targetScrollY = typeof target === 'number' 
    ? target 
    : target.getBoundingClientRect().top + startScrollY;
  const scrollDistance = targetScrollY - startScrollY;
  let startTime = null;

  // 逐帧动画函数
  function animateScroll(currentTime) {
    if (!startTime) startTime = currentTime;
    const timeElapsed = currentTime - startTime;
    // 计算滚动进度,确保不超过100%
    const progress = Math.min(timeElapsed / duration, 1);
    
    // 使用ease-in-out缓动函数,让滚动更自然
    const easedProgress = progress < 0.5 
      ? 2 * progress * progress 
      : 1 - Math.pow(-2 * progress + 2, 2) / 2;
    
    // 更新滚动位置,强制禁用原生平滑避免浏览器干扰
    window.scrollTo({
      top: startScrollY + scrollDistance * easedProgress,
      behavior: 'auto'
    });

    // 未完成时长则继续动画
    if (timeElapsed < duration) {
      requestAnimationFrame(animateScroll);
    }
  }

  requestAnimationFrame(animateScroll);
}

// 绑定锚点点击事件
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
  anchor.addEventListener('click', function(e) {
    e.preventDefault(); // 阻止默认跳转行为
    const targetSelector = this.getAttribute('href');
    if (targetSelector === '#') return;
    
    const targetElement = document.querySelector(targetSelector);
    if (targetElement) {
      smoothScrollTo(targetElement);
    }
  });
});

优势

  • 完全不依赖浏览器设置或原生API,兼容性极强
  • 可自定义滚动时长、缓动效果(比如替换为线性、ease-in等)
  • 避免Edge浏览器flag带来的跳转bug

方案二:强制第三方库使用JS模拟滚动

如果偏好使用第三方库(如smooth-scroll等),需要确保库强制禁用原生平滑滚动,改用JS模拟。以smooth-scroll为例:

// 初始化时强制忽略原生滚动行为
import SmoothScroll from 'smooth-scroll';
new SmoothScroll('a[href^="#"]', {
  speed: 500,
  easing: 'easeInOutCubic',
  ignoreNativeScrollBehavior: true // 关键配置:禁用原生平滑,使用JS模拟
});

注意事项

  • 不同库的配置项名称可能不同,需查阅对应文档(比如有些库叫forceAnimation)
  • 确保库的版本是最新的,避免旧版本存在Edge兼容性问题

关键排查点

  • 检查页面是否存在其他拦截滚动的代码(如overflow: hidden、自定义滚动容器)
  • 确认锚点目标元素的id正确,且元素存在于DOM中
  • 测试时关闭Edge的平滑滚动flag,验证效果是否一致

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 10:55:16