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

滚动容器内元素相对滚动位置获取及平滑滚动实现问题

解决移动端容器内平滑滚动到对应section的问题

问题分析

你遇到的核心问题是用position()获取元素位置根本不靠谱——这个方法返回的是元素相对于最近定位父元素的坐标,当#main-container发生滚动时,这个值会跟着滚动位置动态变化,自然算不出正确的滚动目标位置。

正确的实现方案

我们需要拿到每个section相对于#main-container容器本身的顶部偏移量,这里可以通过offset()方法结合容器自身的偏移来计算:

$(document).ready(function () {
  $('.nav-link').on('click', function () {
    if ($(window).width() < 768) {
      // 获取当前点击导航对应的目标section
      const targetSection = $(".section#" + $(this).attr('id'));
      // 获取section相对于整个文档的顶部偏移
      const sectionDocOffset = targetSection.offset().top;
      // 获取容器相对于整个文档的顶部偏移
      const containerDocOffset = $('#main-container').offset().top;
      // 计算section在容器内部的顶部偏移(这就是我们要滚动到的目标值)
      const scrollTarget = sectionDocOffset - containerDocOffset;

      // 执行平滑滚动动画
      $('#main-container').animate({
        scrollTop: scrollTarget
      }, 500);
    }
  });
});

额外优化提示

  1. 缓存DOM元素提升性能:把重复查询的容器元素缓存起来,减少DOM操作开销:
$(document).ready(function () {
  const $mainContainer = $('#main-container'); // 提前缓存容器
  $('.nav-link').on('click', function () {
    if ($(window).width() < 768) {
      const targetSection = $(".section#" + $(this).attr('id'));
      const scrollTarget = targetSection.offset().top - $mainContainer.offset().top;
      $mainContainer.animate({ scrollTop: scrollTarget }, 500);
    }
  });
});
  1. 原生JS替代方案(无需jQuery):如果项目后期想移除jQuery依赖,也可以用原生API实现同样效果:
document.addEventListener('DOMContentLoaded', function() {
  const mainContainer = document.getElementById('main-container');
  const navLinks = document.querySelectorAll('.nav-link');

  navLinks.forEach(link => {
    link.addEventListener('click', function() {
      if (window.innerWidth < 768) {
        const targetId = this.id;
        const targetSection = document.querySelector(`.section#${targetId}`);
        // 计算目标section在容器内的偏移量
        const scrollTarget = targetSection.offsetTop - mainContainer.offsetTop;
        // 原生平滑滚动
        mainContainer.scrollTo({
          top: scrollTarget,
          behavior: 'smooth'
        });
      }
    });
  });
});

为什么这个方法有效

offset()返回的是元素相对于整个文档的坐标,完全不受容器滚动状态的影响。用section的文档偏移减去容器的文档偏移,得到的就是section在容器内部的固定顶部位置,不管容器有没有滚动,这个值都能精准指向目标位置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 07:59:29