如何在左右滚动事件中判断容器内的子div是否处于居中位置
实现逻辑
offsetLeft是子元素相对于父元素的固定偏移值,不会跟随滚动状态变化,所以无法用来判断滚动时的实时相对位置- 核心判断逻辑是计算滚动容器的视口横向中心点,再依次计算每个子slide的横向中心点,两者差值小于设定阈值时,判定该slide处于居中位置,激活对应导航点
完整实现代码
HTML(原有代码无需修改)
<div class="slider"> <a href="#slide-1">1</a> <a href="#slide-2">2</a> <a href="#slide-3">3</a> <a href="#slide-4">4</a> <a href="#slide-5">5</a> <div class="slides"> <div id="slide-1">1</div> <div id="slide-2">2</div> <div id="slide-3">3</div> <div id="slide-4">4</div> <div id="slide-5">5</div> </div> </div>
JavaScript
const slideContainer = document.querySelector(".slides") const navLinks = document.querySelectorAll('.slider > a') const slides = document.querySelectorAll('.slides > div') // 可自定义阈值,单位px,值越大判定居中的容错范围越大 const CENTER_THRESHOLD = 50 slideContainer.addEventListener('scroll', function() { // 计算容器视口的横向中心点 const containerCenter = slideContainer.scrollLeft + slideContainer.clientWidth / 2 slides.forEach((slide, index) => { // 计算当前slide的横向中心点 const slideLeft = slide.offsetLeft const slideCenter = slideLeft + slide.offsetWidth / 2 // 判断是否在居中阈值范围内 const isCenter = Math.abs(slideCenter - containerCenter) < CENTER_THRESHOLD // 切换导航激活状态 if (isCenter) { navLinks.forEach(link => link.classList.remove('active')) navLinks[index].classList.add('active') } }) })
补充说明
- 可以给
.active类自定义高亮、变色等样式,用来标识当前激活的导航点 - 如果滚动有平滑动画效果,建议配合防抖函数优化性能,避免滚动过程中频繁触发计算逻辑
- 所有逻辑均为原生JS实现,不需要引入任何第三方依赖
内容的提问来源于stack exchange,提问作者Pocket
相关产品推荐
相关产品推荐

