如何基于HTML/CSS实现滚动到图片位置时触发图片动画而非加载即播放
滚动触发图片入场动画的实现方案
第一步:调整原有CSS配置
原CSS在元素初始状态直接绑定了动画属性,会导致页面加载完成立刻执行动画,因此需要把动画的绑定逻辑从“默认生效”调整为“类名触发生效”:
- 保留图片原有布局、尺寸等自定义样式,默认给图片设置动画起始的透明度状态,避免未触发时直接展示内容
- 新增独立的类选择器,仅当元素携带该类名时才挂载对应动画属性
调整后的CSS代码如下:
#clenet_picture { /* 这里保留你原有的宽高、边距等布局样式 */ opacity: 0; /* 对应动画起始状态,未触发时图片隐藏 */ } /* 新增动画触发类 */ #clenet_picture.animate-active { animation-name: image-anim; animation-duration: 4s; animation-fill-mode: forwards; /* 保证动画结束后保持最终的100%透明度状态,不会跳回初始值 */ } @keyframes image-anim { from { opacity: 0; } to { opacity: 1; } }
第二步:使用原生JS实现视口位置检测
采用浏览器原生的IntersectionObserver接口检测图片是否滚动进入可视区域,相比传统的scroll事件监听性能更优,不会造成频繁的页面重排。
对应的JS实现代码:
// 获取目标图片DOM元素 const targetImg = document.getElementById('clenet_picture'); // 创建交叉观察器实例 const imgObserver = new IntersectionObserver((entries) => { entries.forEach(item => { // 判断当前元素是否进入可视范围 if (item.isIntersecting) { // 给元素添加触发动画的类名,启动动画 item.target.classList.add('animate-active'); // 触发完成后停止观察该元素,避免滚动时重复触发动画 imgObserver.unobserve(item.target); } }) }, { // 配置触发阈值:图片露出20%区域时就启动动画,可根据需求调整数值 threshold: 0.2, // 可选配置:设置边距,让图片距离视口底部120px时就提前触发动画,提升体验 rootMargin: '0px 0px 120px 0px' }); // 启动对目标图片的观察 imgObserver.observe(targetImg);
可选优化说明
- 如果页面内存在多个需要同样滚动触发动画的图片,只需要通过类选择器统一获取所有目标元素,循环调用
observe方法加入观察列表即可,不需要重复编写逻辑 - 可根据实际效果调整触发阈值、提前触发的边距参数,适配不同的动画节奏需求
内容的提问来源于stack exchange,提问作者Alexander Svilarov
相关产品推荐
相关产品推荐

