如何实现随用户上下滚动页面切换图片的效果?jQuery mousewheel实现无效求指导
滚动联动的双图平滑切换实现方案
效果实现核心逻辑
这类随滚动动作切换图片的效果,本质是将页面滚动的连续进度映射为两张叠放图片的交叉透明度权重。之前用jQuery mousewheel实现效果不达预期,通常是两个常见原因:一是直接拦截滚轮事件改变状态,和浏览器原生滚动体感冲突;二是没有做动画补间,图片切换生硬跳变。
分步落地流程
- 结构搭建:将两张盒子图做绝对定位叠放在同一固定尺寸的容器内,闭合状态图置于底层,打开状态图置于上层,容器高度设置为和单屏视口高度一致,预留足够的滚动距离承载动画过程。
- 滚动进度采集:放弃监听
mousewheel事件,改用原生scroll事件结合IntersectionObserver采集动画容器的可见比例,计算0-1区间的连续进度值:容器刚进入视口时进度为0(完全展示闭合状态盒子),容器完全滑出视口时进度为1(完全展示打开状态盒子),中间滚动位置对应连续的进度值。 - 平滑效果补全:拿到进度值后,给上层的打开状态图绑定透明度变化,通过
requestAnimationFrame实现动画缓动——哪怕用户快速滚动到任意位置,图片的透明度也会以固定的跟手系数平滑过渡,消除生硬跳变的观感。 - 体感优化:不要对动画容器的滚轮事件做
preventDefault拦截,所有动画逻辑和原生滚动完全解耦,仅将滚动进度作为动画输入参数,避免出现页面滚动卡顿、跳步的问题。
可复用核心代码片段
// 获取DOM节点 const animationWrap = document.querySelector('.box-animation-container'); const openBoxImage = document.querySelector('.img-open-box'); // 动画状态初始化 let currentVisualProgress = 0; // 实际渲染的当前进度 let targetScrollProgress = 0; // 滚动位置对应的目标进度 // 监听容器可见比例 const observer = new IntersectionObserver((entries) => { const record = entries[0]; // 转换为0-1区间的进度值:可见比例从1降到0时,动画进度从0升到1 targetScrollProgress = 1 - record.intersectionRatio; }, { threshold: Array.from({length: 101}, (_, i) => i/101) // 高精度监听变化 }); observer.observe(animationWrap); // 逐帧平滑渲染 function renderFrame() { // 每帧向目标进度靠近15%-20%,实现自然的缓动跟手效果 currentVisualProgress += (targetScrollProgress - currentVisualProgress) * 0.18; openBoxImage.style.opacity = currentVisualProgress; requestAnimationFrame(renderFrame); } renderFrame();
参考素材
- 闭合状态盒子图:

- 打开状态盒子图:

内容的提问来源于stack exchange,提问作者Esme June
相关产品推荐
相关产品推荐

