如何实现内容进入视口时才触发动画效果
实现视口触发进度条动画的方案
核心思路
通过Intersection Observer API监听目标区域是否进入视口,只有当元素出现在屏幕中时,才为进度条添加动画类,触发加载动画。
步骤1:修改CSS样式
移除进度条默认的动画,改为通过类控制动画触发:
.flex-container1 { display: flex; flex-wrap: wrap; } .flex-container1>div { margin: 20px; margin-bottom: 5px; } .progress-bar-ai { position: relative; top: 45px; left: 30px; background-color: #310000; border-radius: 20px; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2); margin: 15px; height: 20px; width: 200px; max-width: 100%; } .progress-ai { position: absolute; top: 3px; right: 3px; background: #EEA808; border-radius: 20px; height: 14px; width: 0; /* 默认宽度设为0,动画从0开始增长 */ transition: width 0.5s ease-in; float: right; } .progress-bar-dw { position: relative; top: 45px; right: 30px; background-color: #480036; border-radius: 20px; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2); margin: 15px; height: 20px; width: 200px; max-width: 100%; } .progress-dw { position: absolute; top: 3px; left: 3px; background: #FF40F0; border-radius: 20px; height: 14px; width: 0; /* 默认宽度设为0 */ transition: width 0.5s ease-in; } /* 新增动画触发类 */ .progress-ai.animate { width: 90%; animation: load 2s normal forwards; } .progress-dw.animate { width: 40%; animation: load 2s normal forwards; } @keyframes load { 0% { width: 0; } }
说明:把进度条默认宽度设为0,添加
.animate类后才设置目标宽度并播放动画,确保初始状态是隐藏的。
步骤2:添加JavaScript监听逻辑
在HTML底部添加以下代码,监听目标容器是否进入视口:
<div class="flex-container1" id="progressContainer"> <div class="progress-bar-ai"> <div data-size="20" class="progress-ai"></div> </div> <div><img class="img-fluid" src="assets/img/icons/Illustrator.png" width="90" height="auto" alt="Illustrator图标" /></div> <div><img class="img-fluid" src="assets/img/icons/Dreamweaver.png" width="90" height="auto" alt="Dreamweaver图标" /></div> <div class="progress-bar-dw"> <div data-size="20" class="progress-dw"></div> </div> </div> <script> // 选择要监听的容器 const progressContainer = document.getElementById('progressContainer'); // 选择所有进度条元素 const progressBars = document.querySelectorAll('.progress-ai, .progress-dw'); // 创建观察者实例 const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { // 容器进入视口时,给所有进度条添加动画类 progressBars.forEach(bar => bar.classList.add('animate')); // 只触发一次,之后停止监听 observer.unobserve(entry.target); } }); }, { threshold: 0.1 // 元素10%进入视口时触发动画 }); // 开始监听目标容器 observer.observe(progressContainer); </script>
说明:
- Intersection Observer是浏览器原生API,无需额外引入库,兼容性覆盖绝大多数现代浏览器
threshold: 0.1可按需调整,比如设为0.5表示元素一半进入视口时触发observer.unobserve(entry.target)确保动画只播放一次,避免重复触发
内容的提问来源于stack exchange,提问作者Bud.420
相关产品推荐
相关产品推荐

