如何实现四个div元素依次循环触发hover动画(CSS+HTML)
解决方案:依次循环播放元素动画
方案一:纯CSS实现(适合固定时长的动画)
假设你已定义好stepped-pulse动画,我们可以通过动画延迟+循环周期对齐的方式实现依次播放。核心思路是让每个元素的动画延迟等于前一个元素的动画时长,同时确保总循环周期为「单元素动画时长 × 元素数量」,避免循环时错位。
代码示例
/* 你的原动画定义(保持不变) */ @keyframes stepped-pulse { 0% { transform: scale(1); opacity: 1; } 50% { transform: scale(1.1); opacity: 0.8; } 100% { transform: scale(1); opacity: 1; } } /* 元素基础样式 */ .ProductBlock { width: 100px; height: 100px; background-color: #eee; margin: 10px 0; } /* 依次设置每个元素的动画规则 */ #rij1 { animation: stepped-pulse 2s infinite; /* 单元素动画时长2秒,无限循环 */ } #rij2 { animation: stepped-pulse 2s infinite; animation-delay: 2s; /* 等待第一个元素动画完成后启动 */ } #rij3 { animation: stepped-pulse 2s infinite; animation-delay: 4s; } #rij4 { animation: stepped-pulse 2s infinite; animation-delay: 6s; }
进阶优化(避免循环错位)
如果动画有复杂关键帧,建议将总循环周期拉长为8秒(2×4),把每个元素的动画片段嵌入对应时间段,确保循环完全对齐:
@keyframes stepped-pulse { /* 0-25% 对应第一个元素的动画周期,25-50%对应第二个,以此类推 */ 0%, 25%, 50%, 75%, 100% { transform: scale(1); opacity: 1; } 12.5% { transform: scale(1.1); opacity: 0.8; } /* 第一个元素的脉冲点 */ 37.5% { transform: scale(1.1); opacity: 0.8; } /* 第二个元素的脉冲点 */ 62.5% { transform: scale(1.1); opacity: 0.8; } /* 第三个元素的脉冲点 */ 87.5% { transform: scale(1.1); opacity: 0.8; } /* 第四个元素的脉冲点 */ } #rij1 { animation: stepped-pulse 8s infinite; } #rij2 { animation: stepped-pulse 8s infinite; animation-delay: -6s; } /* 从第2秒开始播放 */ #rij3 { animation: stepped-pulse 8s infinite; animation-delay: -4s; } /* 从第4秒开始播放 */ #rij4 { animation: stepped-pulse 8s infinite; animation-delay: -2s; } /* 从第6秒开始播放 */
方案二:JavaScript实现(灵活可控,适合动态场景)
如果动画时长不固定或需要更灵活的控制(比如中途暂停、调整顺序),可以通过监听animationend事件,触发下一个元素的动画,循环往复。
代码示例
CSS部分(把动画封装为类)
@keyframes stepped-pulse { 0% { transform: scale(1); opacity: 1; } 50% { transform: scale(1.1); opacity: 0.8; } 100% { transform: scale(1); opacity: 1; } } .ProductBlock { width: 100px; height: 100px; background-color: #eee; margin: 10px 0; } .stepped-pulse { animation: stepped-pulse 2s forwards; /* forwards保持动画结束状态,按需调整 */ }
JavaScript部分
// 获取所有目标元素 const productBlocks = [ document.getElementById('rij1'), document.getElementById('rij2'), document.getElementById('rij3'), document.getElementById('rij4') ]; let currentIndex = 0; // 播放下一个元素的动画 function playNext() { // 移除动画类后强制重绘,确保动画能重新触发 const currentBlock = productBlocks[currentIndex]; currentBlock.classList.remove('stepped-pulse'); void currentBlock.offsetWidth; // 强制浏览器重绘 currentBlock.classList.add('stepped-pulse'); // 更新索引,循环到下一个元素 currentIndex = (currentIndex + 1) % productBlocks.length; } // 监听每个元素的动画结束事件,触发下一个 productBlocks.forEach(block => { block.addEventListener('animationend', () => { setTimeout(playNext, 0); // 延迟0确保当前动画完全结束 }); }); // 初始化启动第一个动画 playNext();
方案优势
- 无需计算固定延迟,自动适配动画时长变化
- 可扩展控制逻辑(比如添加暂停按钮、调整播放顺序)
内容的提问来源于stack exchange,提问作者kite kit
相关产品推荐
相关产品推荐

