将section放入scroll-container后JavaScript滚动函数失效的解决办法
问题根源与解决办法
当把section放入.scroll-container后,你的JS代码失效的核心原因是滚动事件的监听对象、滚动位置的判断目标完全错误,同时存在元素选择、事件重复绑定等问题,具体修正如下:
1. 修正CSS的冗余错误
.scroll-container里重复定义了overflow-y,删掉错误的重复项:
.scroll-container { overflow-y: scroll; height: 100vh; scroll-snap-type: y mandatory; background-position: center; background-size: cover; /* 移除下面这行错误的重复定义 */ /* overflow-y: y mandatory; */ }
2. 核心JS代码修正
错误点拆解
- 原代码监听
document的scroll事件,但实际滚动的是.scroll-container,而非整个文档 - 获取sections的方式错误:
document.querySelector('scroll-container')是找标签名为<scroll-container>的元素,应该用类选择器.scroll-container,且需从容器内获取section - 用
window.pageYOffset判断滚动位置,但实际容器的滚动位置是容器的scrollTop属性 wheel事件绑定在document上,且每次scroll都重复绑定,应该绑定在滚动容器上,且只绑定一次- 错误操作
html的scrollTop,应该操作滚动容器的scrollTop
修改后的完整JS代码
document.lastScrollPosition = 0; document.lastCentered = 0; document.onWayTo = null; let timer = null; $(document).ready(function() { // 获取滚动容器 const scrollContainer = document.querySelector('.scroll-container'); // 获取容器内的所有section const sections = scrollContainer.querySelectorAll('section'); // 监听滚动容器的scroll事件 scrollContainer.addEventListener('scroll', () => { const direction = scrollContainer.scrollTop - document.lastScrollPosition > 0 ? 'down' : 'up'; if (document.onWayTo === null) { const destIndex = direction === 'up' ? document.lastCentered - 1 : document.lastCentered + 1; if (destIndex >= 0 && destIndex < sections.length) { document.onWayTo = destIndex; // 滚动到容器内对应section的位置 scrollContainer.scrollTop = sections[destIndex].offsetTop; } } // 避免重复创建定时器 if (timer) clearInterval(timer); timer = setInterval(() => { sections.forEach((section, index) => { // 判断容器的滚动位置是否等于section的offsetTop if (scrollContainer.scrollTop === section.offsetTop) { clearInterval(timer); document.lastCentered = index; section.className = 'active'; if (document.onWayTo === index) { document.onWayTo = null; } } else { section.className = ''; } }); }, 500); document.lastScrollPosition = scrollContainer.scrollTop; }); // 监听滚动容器的wheel事件,只绑定一次 scrollContainer.addEventListener('wheel', (event) => { event.preventDefault(); const speed = event.deltaY / 0.3; scrollContainer.scrollTop += speed; }, { passive: false }); });
3. 额外说明
- 原HTML中script放在
.scroll-container内部虽然能运行,但更规范的做法是放在</body>闭合前,避免影响DOM加载顺序 - 保留了原有的scroll-snap相关CSS,确保滚动吸附效果正常
内容的提问来源于stack exchange,提问作者David Grillo
相关产品推荐
相关产品推荐

