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

如何使用JS实现滚动时根据方向跳转至下一个/上一个锚点

实现滚动方向触发锚点自动跳转

你已经有了一套点击可跳转至对应锚点的垂直导航栏,现在要实现滚动页面时根据滚动方向,自动跳转到下一个或上一个锚点,以下是具体实现方案:

原始导航栏HTML代码

<div id="top-menu" class="verticalNav textCenter">
  <ul class="bg-dark-transparent">
    <li><a id="scroll1" class="liColor noTextDecoration sideMenu" href="#introduction">Intro</a></li>
    <li><a id="scroll2" class="liColor noTextDecoration sideMenu" href="#overview">Overview</a></li>
    <li><a id="scroll3" class="liColor noTextDecoration sideMenu" href="#process">Process</a></li>
    <li><a id="scroll4" class="liColor noTextDecoration sideMenu" href="#research">Research</a></li>
    <li><a id="scroll5" class="liColor noTextDecoration sideMenu" href="#analysis">Analysis</a></li>
    <li><a id="scroll6" class="liColor noTextDecoration sideMenu" href="#ideation">Ideation</a></li>
    <li><a id="scroll7" class="liColor noTextDecoration sideMenu" href="#prototype">Prototype</a></li>
    <li><a id="scroll8" class="liColor noTextDecoration sideMenu" href="#testing">Testing</a></li>
    <li><a id="scroll9" class="liColor noTextDecoration sideMenu" href="#result">Result</a></li>
  </ul>
</div>

核心实现逻辑(JavaScript)

通过监听滚动事件判断方向,定位当前锚点后触发对应锚点的平滑跳转,同时用防抖避免频繁触发:

// 获取所有导航链接和对应的锚点目标元素
const navLinks = document.querySelectorAll('.sideMenu');
const anchorTargets = Array.from(navLinks).map(link => document.querySelector(link.getAttribute('href')));

// 记录上一次滚动位置,用于判断滚动方向
let lastScrollTop = 0;
// 防抖定时器,防止滚动事件频繁触发
let scrollTimer = null;

// 防抖函数封装
function debounce(func, delay) {
  return function() {
    clearTimeout(scrollTimer);
    scrollTimer = setTimeout(func, delay);
  };
}

// 滚动事件处理逻辑
function handleScroll() {
  const currentScrollTop = window.pageYOffset || document.documentElement.scrollTop;
  const isScrollDown = currentScrollTop > lastScrollTop;
  
  // 找到当前处于视口范围内的锚点索引
  const currentAnchorIndex = anchorTargets.findIndex(target => {
    const rect = target.getBoundingClientRect();
    // 以元素进入视口1/3位置作为触发条件,可根据需求调整
    return rect.top <= window.innerHeight / 3 && rect.bottom >= window.innerHeight / 3;
  });

  if (currentAnchorIndex === -1) {
    lastScrollTop = currentScrollTop;
    return;
  }

  // 根据滚动方向确定目标锚点索引
  let targetIndex;
  if (isScrollDown) {
    targetIndex = currentAnchorIndex + 1;
    // 到达最后一个锚点时停止跳转
    if (targetIndex >= anchorTargets.length) return;
  } else {
    targetIndex = currentAnchorIndex - 1;
    // 到达第一个锚点时停止跳转
    if (targetIndex < 0) return;
  }

  // 平滑滚动到目标锚点
  anchorTargets[targetIndex].scrollIntoView({
    behavior: 'smooth',
    block: 'start' // 可选改为'center'让锚点居中显示
  });

  // 更新导航激活状态(可选,给当前锚点的导航链接加样式)
  navLinks.forEach(link => link.classList.remove('active'));
  navLinks[targetIndex].classList.add('active');

  lastScrollTop = currentScrollTop;
}

// 给窗口绑定防抖后的滚动事件监听
window.addEventListener('scroll', debounce(handleScroll, 300));

可选:添加导航激活状态样式

给当前激活的导航链接加样式,让用户明确当前位置:

.sideMenu.active {
  color: #fff;
  background-color: rgba(0,0,0,0.6);
  /* 可根据需求自定义其他样式 */
}

注意事项

  • 确保页面中存在所有导航链接指向的锚点元素(如id="introduction"、id="overview"等),否则代码会报错。
  • 防抖时间(300ms)可按需调整,数值越大触发越不频繁,反之则更灵敏。
  • 视口触发条件(window.innerHeight / 3)也可自定义,比如改成window.innerHeight / 2,让元素居中时触发跳转。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 18:27:32