真正稳定可行的横向无限滚动方案是css动画+双份文案拼接,因scroll-view存在卡顿、闪屏、重排等问题;需复制文案、动态计算animation-duration、用uni.createselectorquery延迟获取真实宽度并容差处理字体差异。
直接用 scroll-view 做横向无限滚动文字,真机上大概率卡顿、跳帧、ios 闪屏;真正稳定可行的方案是 css 动画 + 双份文案拼接,靠 @keyframes 驱动位移,视觉上“看不出断点”。
为什么 scroll-view 横向滚动不推荐做跑马灯
它默认不支持无缝循环,iOS 微信里一滑就卡、动画掉帧,且 scroll-left 频繁更新会触发重排,性能差;即使硬上定时器+重置逻辑,也要处理字符串拼接(如 "0" + 10 → "010")、浮点误差、平台渲染时机不一致等问题,维护成本远高于 CSS 方案。
-
scroll-with-animation="false"必须写死在模板里,动态绑定无效 -
scroll-left初始值必须是number类型,不能是字符串"0" - 父容器要设固定宽度(如
width: 750rpx),scroll-view加overflow: hidden - 子元素得用
display: inline-block+white-space: nowrap,否则宽度算不准
CSS 动画方案怎么写才真正无缝
核心是让动画结束时,第二份文案刚好完全进入视口,第一份文案刚好完全移出——人眼看不到衔接缝隙。这要求文案复制两遍,且动画时长和内容总宽严格匹配。
- 文案必须拼两份:
marqueeText + marqueeText,单份会导致末尾留白 - 用
animation-duration控制速度,建议按内容像素宽度动态算:每 10px 宽度对应 1s,例如width: 600px→duration: 60s - H5 端可直接用
@keyframes;小程序端需注意:微信基础库 animation-fill-mode: forwards,得 fallback 到 JS 定时重播 - 避免在动画元素内放
rich-text或图片,它们可能触发重绘抖动
怎么判断文字是否真的溢出容器
不能在 onReady 或 mounted 里直接用 offsetWidth > clientWidth 判断——uni-app 多端 DOM 渲染时机不一致,尤其 v-for 渲染多个跑马灯时,常误判为“没溢出”。
- 要用
uni.createSelectorQuery()延迟到下一帧查尺寸 - 配合
setTimeout(() => {}, 0)或 Vue 3 的nextTick(),确保节点已挂载 - 加简单防抖(比如 50ms 内只查一次),避免重复查询拖慢初始化
- 查的是最内层文本容器(如 class="marquee-text" 的
view),不是外层scroll-view
最易被忽略的一点:动画 duration 一旦写死,数据长度变化后就会变快或变慢;真实项目里必须根据文案实际渲染宽度动态计算,而不是靠预估或固定值。另外,多端字体渲染差异会导致宽度浮动,iOS 和 Android 同样文案宽度可能差 2–5px,这个偏差也得纳入 duration 计算容差。











