移动端页面滚动时导航栏匹配锚点后激活div自动滚动的解决方案
实现方案
核心实现思路
- 监听页面垂直滚动事件,配合节流函数优化性能,避免高频触发计算
- 滚动时实时判断当前处于视口内的锚点区块,匹配对应的子导航项并标记激活状态
- 激活项发生变更时,触发你已有的横向滚动逻辑,将对应导航项移动到目标位置
前置准备
给导航项和对应锚点区块增加关联标识,方便匹配:
导航项结构示例:
<div class="sub-nav"> <div class="nav-item" data-target="#section-option">Option</div> <div class="nav-item" data-target="#section-include">What's include</div> <!-- 其他导航项 --> </div>
对应锚点区块结构示例:
<div class="section" id="section-option">...</div> <div class="section" id="section-include">...</div> <!-- 其他区块 -->
完整代码实现
// 节流函数,避免滚动事件高频触发 function throttle(func, delay = 150) { let timer = null; return function(...args) { if (timer) return; timer = setTimeout(() => { func.apply(this, args); timer = null; }, delay); } } // 导航项滚动到可视区域的方法,复用你已有的逻辑 function scrollNavToActive(activeItem) { const $nav = $('.sub-nav'); const pos = $(activeItem).position().left; const currentScroll = $nav.scrollLeft(); const divWidth = $nav.width(); // 这里可以调整除数,3是居中偏左,2是完全居中,0是贴左侧 const targetPos = (pos + currentScroll) - (divWidth / 3); $nav.stop().animate({ scrollLeft: targetPos }, 200); // 动画时长可调整 } // 计算当前激活的区块 function getActiveSection() { const scrollTop = $(window).scrollTop(); // 可调整阈值,控制区块进入视口多少距离后触发激活 const offsetThreshold = 100; let activeId = ''; $('.section').each(function() { const sectionTop = $(this).offset().top - offsetThreshold; const sectionHeight = $(this).outerHeight(); if (scrollTop >= sectionTop && scrollTop < sectionTop + sectionHeight) { activeId = $(this).attr('id'); return false; // 匹配到就终止遍历 } }); return activeId; } // 滚动事件监听 $(window).on('scroll', throttle(function() { const activeId = getActiveSection(); if (!activeId) return; const $activeNav = $(`.nav-item[data-target="#${activeId}"]`); // 只有激活项变化的时候才触发滚动,避免重复执行 if ($activeNav.hasClass('active')) return; $('.nav-item').removeClass('active'); $activeNav.addClass('active'); // 触发导航横向滚动 scrollNavToActive($activeNav); })); // 页面初始加载时触发一次,匹配初始激活项 $(window).trigger('scroll');
注意事项
- 阈值
offsetThreshold可以根据你的页面布局调整,比如固定头部高度较高的话,阈值设为和头部高度一致即可 - 导航栏的固定定位、
overflow-x: auto等样式要提前配置好,同时要设置white-space: nowrap保证导航项不换行 - 如果不需要动画效果,把animate方法换成直接设置scrollLeft即可
内容的提问来源于stack exchange,提问作者Usertoknow
相关产品推荐
相关产品推荐

