H5 循环播放通知栏的实现技巧

131 阅读3分钟

前言

在各类 APP 的活动页面中,循环播放的通知栏十分常见,比较吸引用户的关注,所以要把这一块的展示做好,让用户可以有好的交互。

比如春节期间,某 APP 的通知栏显示「春节期间,部分商品受物流影响延迟发货,请耐心等待,祝你新春快乐!」,这种循环播放的通知栏能有效吸引用户注意。

今天,咱们就来唠唠如何用 H5 实现这种效果。

布局构思

先瞅瞅布局,这可不是普通的左中右布局。当文字向左滚动时,左边的通知图标和右边的留白会挡住文字的一部分。

为实现这效果,容器 box 要设置成相对定位,内部结构分为三部分:content 包裹循环文字,left 是左边的通知图标,设置绝对定位和 left:0;right 是右边留白,设置绝对定位和 right:0。

<div class="box">
  <div class="content">
    <!-- ... 省略 -->
  </div>
  <div class="left">🔔</div>
  <div class="right"></div>
</div>
.box {
  position: relative;
  overflow: hidden;
  /* ... 省略 */
}
.left {
  position: absolute;
  left: 0;
  /* ... 省略 */
}
.right {
  position: absolute;
  right: 0;
  /* ... 省略 */
}

再看看 content,里面包裹了三段一模一样的文字 notice,每段 notice 间有个 space 元素做间距。

<!-- ... 省略 -->
<div id="content">
  <div class="notice">春节期间,部分商品...</div>
  <div class="space"></div>
  <div class="notice">春节期间,部分商品...</div>
  <div class="space"></div>
  <div class="notice">春节期间,部分商品...</div>
</div>
<!-- ... 省略 -->

为啥要放三段一样文字呢?这和循环播放逻辑紧密相关,相当于第一个播放完之后要跟上下一个,让用户没有感知是在循环播放。

动画逻辑

其实,咱们并没有实现真正的循环播放,而是玩了点 “小把戏”,欺骗了用户的视觉。

播放通知时,content 从 0 开始向左移动,当向左移动到 2 * noticeWidth + spaceWidth 时,再继续向左移动就露馅了,因为第三段文字后没第四段。

但如果把 content 向左移动的距离强行从 2 * noticeWidth + spaceWidth 改为 noticeWidth,用户在 box 可视区域内看到的情况基本一样。然后 content 继续向左移动,当移动距离大于等于 2 * noticeWidth + spaceWidth 时,又把距离重新设为 noticeWidth,如此循环,就让用户觉得 content 能一直向左移动。

const content = document.getElementById("content");
const notice = document.getElementsByClassName("notice");
const space = document.getElementsByClassName("space");
const noticeWidth = notice[0].offsetWidth;
const spaceWidth = space[0].offsetWidth;

let translateX = 0;
function move() {
  translateX += 1.5;
  if (translateX >= noticeWidth * 2 + spaceWidth) {
    translateX = noticeWidth;
  }
  content.style.transform = `translateX(${-translateX}px)`;
  requestAnimationFrame(move);
}

move();

这里用 requestAnimationFrame 替代 setInterval,能保证动画更丝滑,不会出现肉眼可见的卡顿。

总结

用 H5 实现循环播放通知栏,布局上需用绝对定位的通知图标、留白挡住循环文字两侧,循环文字要额外复制两份;

逻辑上,通知栏向左移动 2 * noticeWidth + spaceWidth 后,强制把移动距离从 2 * noticeWidth + spaceWidth 变为 noticeWidth,欺骗用户视觉,达成循环播放效果。

这就是本期要分享的前端h5的消息通知滚动,你更加好的实现方式?欢迎在评论群进行讨论。