文字跑马灯效果指的是文字在固定区域内循环滚动展示,当文字滚动到边界后会重新从另一侧进入,形成连续的滚动视觉。这种效果在网页公告栏、活动宣传栏等场景中应用非常广泛,下面介绍3种常见的js实现技巧。

方法一:基于setInterval定时器实现
这是最基础的实现方式,核心思路是通过定时器不断修改文字容器的偏移量,当偏移量超过文字总宽度时重置偏移,实现循环滚动。
首先准备HTML结构,需要一个固定宽度的外层容器和内部滚动的文字元素:
<div class="marquee-container"> <div class="marquee-text">这是一段需要滚动展示的文字内容,用于演示跑马灯效果</div> </div>
对应的CSS样式设置容器溢出隐藏,文字元素不换行:
.marquee-container {
width: 300px;
overflow: hidden;
white-space: nowrap;
border: 1px solid #ccc;
padding: 10px 0;
}
.marquee-text {
display: inline-block;
white-space: nowrap;
}
js逻辑部分通过定时器修改文字元素的transform偏移值:
// 获取元素
const container = document.querySelector('.marquee-container');
const text = document.querySelector('.marquee-text');
// 滚动速度,单位px/次
const speed = 1;
// 初始偏移量
let offset = 0;
// 定时器间隔,单位ms
const interval = 16;
// 启动定时器
const timer = setInterval(() => {
// 获取容器宽度和文字宽度
const containerWidth = container.offsetWidth;
const textWidth = text.offsetWidth;
// 更新偏移量
offset -= speed;
// 如果文字完全滚出容器左侧,重置偏移到容器右侧
if (-offset >= textWidth) {
offset = containerWidth;
}
// 应用偏移
text.style.transform = `translateX(${offset}px)`;
}, interval);
// 可选:鼠标悬停时暂停滚动
container.addEventListener('mouseenter', () => {
clearInterval(timer);
});
container.addEventListener('mouseleave', () => {
// 重新启动定时器
setInterval(() => {
offset -= speed;
if (-offset >= textWidth) {
offset = containerWidth;
}
text.style.transform = `translateX(${offset}px)`;
}, interval);
});
方法二:基于requestAnimationFrame实现
requestAnimationFrame是浏览器提供的动画API,相比setInterval更适合做动画效果,它的刷新频率和浏览器渲染频率一致,不会出现丢帧问题,性能更优。
HTML和CSS结构和第一种方法一致,js部分替换为以下逻辑:
const container = document.querySelector('.marquee-container');
const text = document.querySelector('.marquee-text');
const speed = 0.5;
let offset = 0;
let animationId = null;
// 动画函数
function animate() {
const containerWidth = container.offsetWidth;
const textWidth = text.offsetWidth;
offset -= speed;
if (-offset >= textWidth) {
offset = containerWidth;
}
text.style.transform = `translateX(${offset}px)`;
// 请求下一帧动画
animationId = requestAnimationFrame(animate);
}
// 启动动画
animationId = requestAnimationFrame(animate);
// 鼠标悬停暂停
container.addEventListener('mouseenter', () => {
cancelAnimationFrame(animationId);
});
container.addEventListener('mouseleave', () => {
animationId = requestAnimationFrame(animate);
});
这种方式不需要自己控制时间间隔,浏览器会自动在合适的时机执行动画回调,动画流畅度更高,适合对性能要求较高的场景。
方法三:CSS animation配合js控制实现
这种方式将动画逻辑交给CSS处理,js只负责控制动画的启停和参数配置,代码更简洁,也便于维护。
HTML结构不变,CSS部分添加动画定义:
.marquee-container {
width: 300px;
overflow: hidden;
white-space: nowrap;
border: 1px solid #ccc;
padding: 10px 0;
}
.marquee-text {
display: inline-block;
white-space: nowrap;
/* 定义动画 */
animation: marquee 10s linear infinite;
}
/* 动画关键帧 */
@keyframes marquee {
0% {
transform: translateX(100%);
}
100% {
transform: translateX(-100%);
}
}
如果需要动态控制动画,比如修改滚动速度、暂停播放,可以通过js修改CSS变量或者动画属性:
const text = document.querySelector('.marquee-text');
// 动态修改动画时长,改变滚动速度
function changeSpeed(duration) {
text.style.animationDuration = `${duration}s`;
}
// 暂停动画
function pauseMarquee() {
text.style.animationPlayState = 'paused';
}
// 继续动画
function resumeMarquee() {
text.style.animationPlayState = 'running';
}
// 示例:鼠标悬停暂停
text.parentElement.addEventListener('mouseenter', pauseMarquee);
text.parentElement.addEventListener('mouseleave', resumeMarquee);
这种方式的动画性能最好,因为CSS动画可以由浏览器的合成层处理,不会触发重排重绘,适合简单固定的跑马灯场景。
三种方法对比
可以根据项目需求选择合适的方法,三者的特点对比如下:
| 实现方式 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| setInterval定时器 | 逻辑简单,兼容性好 | 可能出现丢帧,性能一般 | 简单场景,不需要高流畅度 |
| requestAnimationFrame | 动画流畅,性能优于定时器 | 需要手动控制动画循环 | 需要高流畅度的动态效果 |
| CSS animation配合js | 性能最优,代码简洁 | 复杂逻辑控制不够灵活 | 固定样式的跑马灯场景 |
JavaScript文字跑马灯setIntervalrequestAnimationFrameCSS_animation修改时间:2026-07-08 03:12:34