如何使用原生JS实现无间隙无限垂直跑马灯及悬停停止动画
垂直无限跑马灯无空隙+悬停暂停实现
一、消除循环衔接空白的核心逻辑
跑马灯出现循环空隙的根本原因是:动画滚完设定距离后直接切回起始位置,没有后续内容承接衔接。解决思路非常直接:把现有.slot列表的内容完整克隆一份,追加到原内容末尾,让动画滚动的总距离刚好等于单份内容的总高度——当第一份内容完全滚出可视区域时,克隆的第二份内容刚好无缝补位,动画重置回起始位置的过程用户完全感知不到,自然不会出现空隙。
具体代码调整
- 补全容器基础CSS配置,给可视区域加溢出裁切:
.main-wrapper { /* 和单份slot总高度保持一致的可视区高度 */ height: 570px; overflow: hidden; position: relative; } .animationDiv { position: absolute; top: 0; left: 0; /* 应用匀速循环动画 */ animation: slider 12s linear infinite; } @keyframes slider { 0% { top: 0; } 100% { /* 滚动距离完全等于单份slot的总高度即可 */ top: -570px; } } - 用原生JS完成内容克隆,这是消除空白的关键步骤:
const animationDiv = document.querySelector('.animationDiv'); // 把现有所有slot的内容完整复制一份,追加到原内容后面 const originalContent = animationDiv.innerHTML; animationDiv.innerHTML += originalContent;
如果后续slot内容、高度不是固定值,不要硬编码570px的滚动距离,可以用JS动态计算单份内容高度,同步更新关键帧参数,避免高度不匹配产生空隙:
// 克隆完成后,单份内容高度 = 容器总高度 / 2 const singleListHeight = animationDiv.scrollHeight / 2; // 动态更新关键帧的滚动距离 const targetSheet = document.styleSheets[0]; for (let rule of targetSheet.cssRules) { if (rule.name === 'slider') { rule.deleteRule('100%'); rule.appendRule('100%', `top: -${singleListHeight}px`); } }
二、鼠标悬停暂停动画实现
不需要复杂JS逻辑,直接通过CSS选择器匹配悬停状态即可实现全区域动画暂停:
/* 鼠标悬停在跑马灯可视区域内时,暂停所有运行的动画 */ .main-wrapper:hover .animationDiv { animation-play-state: paused; }
只要鼠标在跑马灯可视范围内,不管落在哪个slot元素上,动画都会立即暂停;鼠标移出区域后动画会从暂停的位置继续播放,不会跳变。
常见注意事项
- 一定要给可视容器加
overflow: hidden,避免滚动过程中溢出的内容影响页面其他布局 - 克隆内容时不要改动原slot的边距、间距样式,否则会因为边距累加出现衔接空隙
- 动画必须使用
linear匀速缓动,否则滚动速度不统一,在循环衔接点会出现明显跳变
内容的提问来源于stack exchange,提问作者SkyStar
相关产品推荐
相关产品推荐

