使用原生Vanilla JavaScript实现滚动时固定多个元素
实现自定义滚动固定(Pin)效果(ES6 版)
嘿,作为 JavaScript 初学者想自己实现 ScrollMagic 的固定效果,这个想法超赞!咱们不用依赖第三方库,用纯 ES6 就能搞定页面滚动时固定不同区块的功能,下面一步步给你拆解实现过程:
第一步:补充基础样式(CSS)
先给元素设置基础样式,让每个区块足够高才能看到滚动固定的效果,同时定义好固定定位的规则:
body { margin: 0; padding: 0; } .forewords { height: 100vh; display: flex; align-items: center; justify-content: center; background: #f0f0f0; } .wrapper { position: relative; } .project { height: 100vh; display: flex; align-items: center; justify-content: center; font-size: 2rem; transition: all 0.3s ease; } /* 固定状态的类 */ .project.pinned { position: fixed; top: 0; left: 0; right: 0; } /* 给每个区块加不同背景方便区分 */ #item1 { background: #ffcccc; } #item2 { background: #ccffcc; } #item3 { background: #ccccff; }
第二步:ES6 核心逻辑实现
用 ES6 的const/let、箭头函数等语法写核心逻辑,清晰易懂:
// 确保DOM加载完成后再执行代码 document.addEventListener('DOMContentLoaded', () => { // 获取所有需要固定的区块 const sections = document.querySelectorAll('.project'); // 获取视口高度 const viewportHeight = window.innerHeight; // 滚动时的处理函数 const handleScroll = () => { const scrollY = window.scrollY; // 遍历每个区块,判断是否需要固定 sections.forEach((section) => { const sectionTop = section.offsetTop; const sectionBottom = sectionTop + section.offsetHeight; // 当滚动到区块顶部,且未滚过区块底部时,添加固定类 if (scrollY >= sectionTop && scrollY < sectionBottom) { section.classList.add('pinned'); } else { section.classList.remove('pinned'); } }); }; // 初始化时先执行一次,保证初始状态正确 handleScroll(); // 添加滚动监听 window.addEventListener('scroll', handleScroll); });
第三步:优化与扩展说明
- 上面的代码会让每个区块在滚动到它的顶部时固定在视口顶部,直到滚动过整个区块后取消固定,下一个区块接着触发固定效果。
- 如果想要更贴合 ScrollMagic 的高级固定逻辑(比如滚动到指定偏移量才触发,固定一段时间后释放),可以调整判断条件,比如设置触发固定的偏移值。
- 滚动事件可以用
requestAnimationFrame做节流优化,避免频繁触发影响性能:
// 优化版滚动监听,减少触发频率 let ticking = false; const optimizedHandleScroll = () => { if (!ticking) { window.requestAnimationFrame(() => { handleScroll(); ticking = false; }); ticking = true; } }; window.addEventListener('scroll', optimizedHandleScroll);
这样你就能用纯 ES6 实现类似 ScrollMagic 的固定效果啦,完全不需要依赖第三方库,很适合初学者理解滚动事件和元素定位的核心原理~
内容的提问来源于stack exchange,提问作者—
相关产品推荐
相关产品推荐

