微信小程序列表项文本横向无缝滚动优化实践

1. 为什么我们需要“无缝”滚动?

做微信小程序开发,尤其是电商、榜单这类信息展示密集的场景,你肯定遇到过这个头疼的问题:列表里某个字段,比如商品名称、新闻标题,它太长了!在小屏幕的手机上,固定宽度的容器根本装不下。直接截断显示“...”吧,信息不完整,用户体验差;换行显示吧,又破坏了列表整齐的布局,显得很乱。

这时候,横向滚动显示就成了一个很自然的选择。让文字像跑马灯一样动起来,既能完整展示信息,又能保持界面整洁。我最早也是这么想的,网上搜一圈,很多教程都教你用 setInterval 或者 setTimeout 定时器,不断去修改元素的 margin-left 或者 transform 值。我试过,对于单个横幅、公告栏这种场景,确实简单够用。

但我的需求不一样。我手头这个项目是一个上下无限滚动的榜单列表,用的是微信小程序的 swiper 组件做垂直轮播。列表里的每一项,都有一个需要横向滚动的商品名称。你想想,如果列表有10条数据,每条数据我都给它绑一个 setInterval 定时器,10个定时器同时在后台跑,还要考虑页面隐藏、切后台时的清理……这个性能开销和潜在的内存泄漏风险,光是想想就让人头皮发麻。所以,我一开始就定了个死规矩:坚决不用定时器,只用纯CSS方案

纯CSS动画性能更好,由浏览器(或小程序引擎)原生优化,但这就引出了我们标题里的核心挑战:“无缝”。你写一个简单的从左到右移动的动画,文字滚出容器后,右边会留下一大片空白,要等动画循环重启,文字“跳回”起点,视觉上会有明显的卡顿和断层,一点也不“丝滑”。我们想要的,是类似春晚字幕那种,首尾相接、连绵不绝的滚动效果。这就是“无缝滚动”要解决的核心问题:如何让动画的结束状态能平滑地衔接回开始状态,让用户察觉不到循环点

2. 核心思路:用“影子”文本制造循环假象

要实现无缝,关键就在于“欺骗”用户的眼睛。我们不能让文本区域真的变空。想象一下,如果文字A在滚动,当它的尾巴快要离开屏幕时,我们能立刻在它后面“变出”一个文字A的复制品来接上,那么视觉上,就永远有文字在滚动,没有空隙。

这就是最实用、兼容性最好的核心思路:双份文本 + 巧妙的 padding

具体怎么做呢?我们不会真的去动态复制DOM节点,那样太耗性能。我们直接在结构里就放两份一模一样的文本内容。比如商品名称是“高端旗舰智能手机2024超长续航版”,那我们就在滚动容器里放两个 <text> 节点,内容都是它。

<view class="scroll-text-warp">
  <text class="scroll-text">{
  
  {item.goods}}</text>
  <text class="scroll-text">{
  
  {item.goods}}</text>
</view>

光这样还不够。我们给 .scroll-text 设置一个 animation,让它从 transform: translateX(0%) 运动到 transform: translateX(-100%)。这个 -100% 指的是它自身宽度的100%。意思是,第一个文本会向左移动,直到它自己的左边缘对齐容器的左边缘(也就是完全移出容器)。

这时,第二个文本(我们叫它“影子文本”)就派上用场了。在动画开始时,第二个文本紧挨着第一个文本的右侧。当第一个文本向左移动时,第二个文本也跟着一起向左移动。在第一个文本刚好完全移出容器的瞬间,第二个文本正好完全进入容器,占据原来第一个文本的位置。从用户的视角看,容器内的文字内容没有中断,只是持续地在向左流动。

但是,这里有个细节问题:当第一个文本刚开始移动时,它的右侧紧跟着第二个文本,这会导致容器内的总内容宽度是单个文本的两倍。我们的动画是移动 -100%(一个文本的宽度),那么移动结束后,容器内显示的正好是第二个文本,完美衔接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值