如何使用JavaScript视差效果精准触发指定区域的动画
实现滚动到对应区域才触发的视差效果
问题分析
当前代码的问题是:所有带.scroll/.scroll2类的元素会随着页面滚动同步变换位置,不管它们是否出现在视口中。要实现仅当元素进入视口时才启动视差动画,核心是要先判断元素是否处于当前可见区域内。
解决方案
1. 实现视口检测函数
先写一个工具函数,判断元素是否进入视口(可自定义触发阈值,以下逻辑为元素只要有一部分进入视口就触发):
function isInViewport(element) { const rect = element.getBoundingClientRect(); return ( rect.top <= window.innerHeight && rect.bottom >= 0 ); }
2. 修改滚动事件逻辑
在滚动事件中,先检查每个目标元素是否在视口内,只有满足条件的元素才应用视差变换,同时加入节流优化性能:
// 节流函数:减少滚动事件触发频率,避免页面卡顿 function throttle(func, delay) { let lastCall = 0; return function(...args) { const now = Date.now(); if (now - lastCall >= delay) { lastCall = now; func.apply(this, args); } }; } // 视差滚动处理函数 function handleParallaxScroll() { const targets = document.querySelectorAll('.scroll, .scroll2'); targets.forEach(target => { // 跳过不在视口内的元素,可选择重置位置 if (!isInViewport(target)) { target.style.transform = 'translate3d(0px, 0px, 0px)'; return; } // 仅处理在视口内的元素 const scrollY = window.pageYOffset; const elementTop = target.getBoundingClientRect().top + scrollY; // 计算元素进入视口后的滚动距离 const scrollDistance = scrollY - elementTop + window.innerHeight; if (target.dataset.direction === 'vertical') { // 调整系数避免位移过大,可根据需求修改 const pos = scrollDistance * (target.dataset.rate / 10); target.style.transform = `translate3d(0px, ${pos}px, 0px)`; } else { const posX = scrollDistance * (target.dataset.ratex / 10); const posY = scrollDistance * (target.dataset.ratey / 10); target.style.transform = `translate3d(${posX}px, ${posY}px, 0px)`; } }); } // 绑定节流后的滚动事件 window.addEventListener('scroll', throttle(handleParallaxScroll, 16)); // 页面加载时触发一次,确保初始位置正确 window.addEventListener('load', handleParallaxScroll);
3. 优化CSS(可选)
调整section高度和布局,让视差效果更自然:
body { margin: 0; font-size: 5em; font-family: 'Montserrat'; font-weight: bold; } section { min-height: 100vh; /* 确保section占满视口高度 */ overflow: hidden; display: flex; align-items: center; justify-content: center; } .sec ul, ul { list-style-type: none; padding: 0; margin: 0; display: grid; grid-template-columns: repeat(3, auto); gap: 1rem; } .bg-0{ background-color: blue; background-attachment: fixed; background-position: center; height: 50vh; }
4. HTML结构保持不变
你的原有HTML结构无需调整,可直接使用。
关键改进点
- 视口检测:通过
getBoundingClientRect()获取元素相对于视口的位置,精准判断可见性 - 相对位移计算:基于元素进入视口后的滚动距离计算位移,确保元素进入视口才开始动
- 性能优化:节流函数减少滚动事件触发次数,避免频繁DOM操作导致的性能问题
内容的提问来源于stack exchange,提问作者Pavel Ants
相关产品推荐
相关产品推荐

