求助:如何为各阶段模块添加onscroll滚动事件实现背景高亮效果
解决滚动时阶段模块背景高亮的问题
我看了你的代码,发现几个关键问题导致滚动高亮效果没正常工作,咱们一步步来修复:
原代码的核心问题
- 逻辑判断矛盾:你的
else分支里,先判断scrollTop > 100,但这个分支只有在scrollTop <=50的时候才会进入,所以这部分代码永远不会执行,而且phases3的高亮逻辑也完全错位了。 - 固定scrollTop值不灵活:用固定的50、100像素来判断,在不同屏幕尺寸下效果会不一致,而且没法准确对应每个模块的位置。
- 类名替换方式不合理:直接赋值
className会覆盖元素原有的类(比如phases-col),导致原有样式失效。
修复后的完整代码
HTML(给所有phase模块统一用类选择器,无需单独id也能批量处理)
<section class="phases"> <div class="row-padding"> <div class="row"> <div class="phases-col"> <img class="phases1" src="/images/1645177223057.png" /> <h3>Phase1</h3> <p>Lorem ipsum, dolor sit amet consectetur adipisicing elit. Repellendus, minus eius earum necessitatibus reprehenderit, excepturi soluta, cumque sed maiores in doloremque assumenda? Eum, officia? Praesentium aspernatur neque atque numquam iste.</p> </div> <div class="phases-col"> <img class="phases1" src="/images/1645177161131.png" /> <h3>Phase2</h3> <p>Lorem ipsum, dolor sit amet consectetur adipisicing elit. Repellendus, minus eius earum necessitatibus reprehenderit, excepturi soluta, cumque sed maiores in doloremque assumenda? Eum, officia? Praesentium aspernatur neque atque numquam iste.</p> </div> <div class="phases-col"> <img class="phases1" src="/images/1645176961476.png" /> <h3>Phase3</h3> <p>Lorem ipsum, dolor sit amet consectetur adipisicing elt. Repellendus, minus eius earum necessitatibus reprehenderit, excepturi soluta, cumque sed maiores in doloremque assumenda? Eum, officia? Praesentium aspernatur neque atque numquam iste.</p> </div> </div> </div> </section>
CSS(保留原有样式,添加过渡动画优化体验)
.phases-col { /* 保留你的基础布局样式,比如 padding、margin 等 */ transition: background-color 0.3s ease; /* 背景色变化添加平滑过渡 */ } .background-scroll { background-color: rgb(0, 0, 0, 0.521); border-radius: 20px; } .nobackground { background-color: rgba(0, 0, 0, 0); }
JavaScript(优化逻辑,添加视口检测和防抖)
// 防抖函数:减少滚动事件触发频率,避免性能浪费 function debounce(func, delay = 100) { let timeoutId; return function() { clearTimeout(timeoutId); timeoutId = setTimeout(() => func.apply(this, arguments), delay); }; } // 检测元素是否进入视口核心逻辑 function isElementInViewport(el) { const rect = el.getBoundingClientRect(); // 当元素进入视口70%时触发高亮(可自行调整这个比例) return rect.top <= window.innerHeight * 0.7 && rect.bottom >= 0; } // 滚动时的处理逻辑 function handleScroll() { const phaseElements = document.querySelectorAll('.phases-col'); phaseElements.forEach(el => { if (isElementInViewport(el)) { el.classList.add('background-scroll'); el.classList.remove('nobackground'); } else { el.classList.remove('background-scroll'); el.classList.add('nobackground'); } }); } // 绑定防抖后的滚动监听 document.addEventListener('scroll', debounce(handleScroll)); // 页面加载时先执行一次,确保初始状态正确 window.addEventListener('load', handleScroll);
关键改进点说明
- 视口检测逻辑:用
getBoundingClientRect()获取元素实时位置,判断是否进入视口,比固定scrollTop值更准确,适配各种屏幕尺寸。 - 防抖处理:滚动事件每秒会触发几十次,防抖函数让处理逻辑在滚动停止后再执行,大幅减少性能消耗。
- 类名操作优化:用
classList.add()/remove()切换类,不会覆盖元素原有的phases-col类,保证基础布局样式正常。 - 过渡动画:给
.phases-col添加transition属性,让背景色变化更平滑,提升用户体验。
你可以根据需求调整isElementInViewport里的window.innerHeight * 0.7这个值,0.5表示元素进入视口一半时触发,0.8表示进入80%时触发,按需调整即可。
内容的提问来源于stack exchange,提问作者Vincenzo Pendino
相关产品推荐
相关产品推荐

