尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

原生 JS 实现垂直无缝滚动跑马灯

原生 JS 实现垂直无缝滚动跑马灯 前言在后台管理系统、H5 活动页面、网站首页经常会看到垂直公告跑马灯多条消息自动向上滚动实现公告、中奖名单、消息通知轮播。网上很多简易跑马灯重置的时候会闪烁本文采用transform transition实现平滑动画利用双层 setTimeout 解决无缝循环闪烁问题同时增加暂停标记可扩展鼠标移入暂停、移出继续播放纯原生 JS不依赖 jQuery。实现特点垂直向上滚动、动画平滑、无缝循环不闪烁、支持暂停控制单条高度可配置。完整源码!DOCTYPE html html langzh-CN head meta charsetUTF-8 title原生JS垂直无缝跑马灯/title style .marquee_box { width: 320px; height: 38px; /* 可视区域高度 单条高度只展示一条 */ overflow: hidden; border: 1px solid #eee; border-radius: 4px; } .marquee_wrap { transition: transform 0.5s ease; } .marquee_item { height: 38px; line-height: 38px; font-size: 14px; padding: 0 10px; white-space: nowrap; } /style /head body !-- 跑马灯DOM结构外层可视盒子内层滚动容器 -- div idmarquee_box classmarquee_box div idmarquee_wrap classmarquee_wrap div classmarquee_item恭喜用户001获得一等奖/div div classmarquee_item恭喜用户002获得二等奖/div div classmarquee_item恭喜用户003获得参与奖/div div classmarquee_item恭喜用户004获得优惠券/div /div /div script // 跑马灯相关js const marquee_box document.getElementById(marquee_box); // 可视盒子 const marquee_wrap document.getElementById(marquee_wrap); // 滚动容器 const marquee_itemHeight 38; // 单条高度 let marquee_index 0; // 当前滚动到第几条偏移量倍数 let marquee_timer null; // 定时器id let marquee_isPause false; // 是否暂停标记 // 切换函数 function changeNotice() { if (marquee_isPause) { return; } marquee_index; marquee_wrap.style.transform translateY(-${marquee_index * marquee_itemHeight}px); // 当滚动完所有条目重置索引无缝循环 if (marquee_index marquee_wrap.children.length) { // 等过渡动画结束后重置位置不产生闪烁 setTimeout(() { marquee_index 0; marquee_wrap.style.transition none; marquee_wrap.style.transform translateY(0); // 恢复过渡动画 setTimeout(() { marquee_wrap.style.transition transform 0.5s ease; }, 20) }, 400) } } // 5秒切换跑马灯 function startMarquee() { marquee_timer setInterval(changeNotice, 5000); } // 启动跑马灯 startMarquee(); // 【可选扩展】鼠标移入暂停鼠标移出继续 marquee_box.addEventListener(mouseenter, function () { marquee_isPause true; }) marquee_box.addEventListener(mouseleave, function () { marquee_isPause false; }) // 页面销毁清除定时器防止内存泄漏 window.addEventListener(beforeunload, () { clearInterval(marquee_timer); }) /script /body /htmlDOM 与 CSS 说明div idmarquee_box !-- 可视容器overflow:hidden 裁切超出内容 -- div idmarquee_wrap !-- 滚动容器通过transform做位移 -- div classmarquee_item条目1/div div classmarquee_item条目2/div /div /divmarquee_box可视盒子固定高度overflow:hidden只显示一条公告marquee_wrap滚动容器使用transform: translateY()垂直位移配合transition实现平滑滚动动画marquee_item单条公告高度固定代码中marquee_itemHeight要和 css 高度保持一致核心代码逐行解析变量说明表格变量作用marquee_box外层可视盒子marquee_wrap滚动内容容器marquee_itemHeight单条条目高度位移计算基准marquee_index当前滚动索引记录当前是第几条marquee_timer定时器 ID用于清除轮播marquee_isPause暂停标记控制是否继续滚动changeNotice () 滚动核心函数function changeNotice() { // 如果标记为暂停直接return不执行滚动 if (marquee_isPause) { return; } marquee_index; // 向上偏移索引 * 单条高度 marquee_wrap.style.transform translateY(-${marquee_index * marquee_itemHeight}px); // 判断滚动到最后一条了准备重置 if (marquee_index marquee_wrap.children.length) { setTimeout(() { marquee_index 0; marquee_wrap.style.transition none; // 关闭动画瞬间归位不会出现反向回退动画 marquee_wrap.style.transform translateY(0); setTimeout(() { marquee_wrap.style.transition transform 0.5s ease; // 重新开启动画 }, 20) }, 400) // 400ms 和动画时长保持一致等滚动动画完全结束再重置 } }重点解决闪烁原理 当滚动到最后一条先等待动画播放完毕再关闭 transition瞬间把容器位置归位到 0 短暂延迟后再重新开启 transition下一次滚动继续有动画。 如果不关闭 transition 直接归位会看到内容回弹向下滚动出现明显闪烁。startMarquee () 启动轮播function startMarquee() { marquee_timer setInterval(changeNotice, 5000); }每隔 5s 执行一次滚动函数可自行修改时间比如 3000 代表 3 秒切换。扩展鼠标悬停暂停marquee_box.addEventListener(mouseenter, function () { marquee_isPause true; }) marquee_box.addEventListener(mouseleave, function () { marquee_isPause false; })鼠标移入公告区域暂停滚动鼠标离开继续后台系统公告常用交互。其他拓展方向横向跑马灯把translateY改成translateX高度改为宽度。增加上下手动点击翻页按钮。文字超出单行省略css 增加text-overflow:ellipsis。多条同时展示修改 marquee_box 可视高度为 N*marquee_itemHeight。知识点总结transform位移相比 top/left开启 GPU 加速性能更好动画流畅transition控制过渡动画重置位置时临时关闭动画解决无缝轮播闪烁setInterval做定时轮播使用标记变量控制暂停不销毁定时器适合频繁 hover 暂停场景定时器用完要清除防止内存泄漏固定高度垂直跑马灯单条高度 JS 和 CSS 必须统一
返回列表