如何实现滚动时图片在指定区域内的正确位移效果?
解决滚动时两张图片在指定区域内反向移动的问题
问题根源
- 定位方式错误:
.top-image和.bottom-image使用fixed定位,完全脱离父元素.front-image的文档流,导致父元素的overflow:hidden无法约束图片,自然会超出指定区域。 - 滚动逻辑不合理:直接用全局
scrollY除以元素高度计算偏移,没有考虑元素在视口中的可见范围,导致图片移动幅度不受控,表现怪异。 - 性能问题:
scroll事件触发频率极高,未做节流处理,加上transition动画叠加,导致动画不流畅。
修正后的代码
CSS 代码
body { height: 300vh; } .front-image { top: 20%; position: relative; padding-top: 96.2px; overflow: hidden; /* 明确设置父元素高度,确保偏移计算基准准确 */ height: 525px; } .front-image .top-image, .front-image .bottom-image { /* 改为absolute定位,绑定父元素范围 */ position: absolute; width: 200px; } .front-image .top-image { top: 0; right: 10%; } .front-image .bottom-image { bottom: 0; left: 10%; } .front-image .content picture img { width: 100%; height: 525px; object-fit: cover; }
JS 代码
const frontImageSection = document.querySelector('.front-image'); const topImage = document.querySelector('.top-image'); const bottomImage = document.querySelector('.bottom-image'); // 节流函数,控制滚动事件触发频率,优化性能 function throttle(func, delay = 16) { let timer = null; return function(...args) { if (!timer) { timer = setTimeout(() => { func.apply(this, args); timer = null; }, delay); } }; } function handleScroll() { const scrollPosition = window.scrollY; const windowHeight = window.innerHeight; const sectionTop = frontImageSection.offsetTop; const sectionHeight = frontImageSection.offsetHeight; const imageHeight = topImage.offsetHeight; // 计算元素在视口中的滚动进度:0(完全在视口上方)→1(完全在视口下方) const progress = Math.max(0, Math.min(1, (scrollPosition - sectionTop + windowHeight) / (sectionHeight + windowHeight))); // 计算图片最大可移动范围,确保不会超出父元素边界 const maxTopOffset = sectionHeight - imageHeight; const maxBottomOffset = -(sectionHeight - imageHeight); // 根据进度计算偏移量,实现反向移动效果 const topOffset = progress * maxTopOffset; const bottomOffset = progress * maxBottomOffset; topImage.style.transform = `translateY(${topOffset}px)`; bottomImage.style.transform = `translateY(${bottomOffset}px)`; } // 绑定节流后的滚动事件 window.addEventListener('scroll', throttle(handleScroll));
改动说明
- 定位调整:将图片的
fixed改为absolute,使其相对于父元素.front-image定位,配合父元素的overflow:hidden,彻底解决图片超出区域的问题。 - 滚动逻辑优化:基于元素在视口中的可见进度计算偏移,进度值被限制在0-1之间,确保图片移动完全在父元素范围内。
- 性能优化:添加节流函数将滚动事件触发频率控制在约60fps,同时移除CSS的
transition,避免动画冲突导致的卡顿。 - 明确父元素高度:给
.front-image设置固定高度,保证偏移计算的基准稳定准确。
内容的提问来源于stack exchange,提问作者sfarzoso
相关产品推荐
相关产品推荐

