news 2026/7/7 3:55:41

alipay-mini-scroll-tip

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
alipay-mini-scroll-tip

支付宝小程序实现「滚动收起、停顿展开」底部订阅提示

一块钉在屏幕下方的订阅提示,滚动时悄悄藏起来,松手后再悄悄露出来——需求很短,但藏着的细节不少。

一、需求场景

在支付宝小程序里,有一块固定在屏幕下方的订阅提示区域,希望达到这样的交互:

  • 用户主动滑动页面时,提示区域隐藏
  • 用户停止滑动后,提示区域重新显示

效果如下图所示(动图演示滚动与停顿时的状态切换):

二、思路拆解

把需求翻译成技术语言,其实要做的事情就是两件:

  1. 监听页面滚动,滚动发生时把区域隐藏
  2. 监听滚动停止,停止后再把区域显示回来。

听起来很简单,但支付宝小程序(其实是各大小程序都一样)并没有原生提供"滚动结束"事件。翻官方文档,唯一与滚动相关的 API 是:

事件名触发时机回调参数
onPageScroll页面滚动时触发scrollHeight(页面总高度)、scrollTop(滚动距离顶部高度)

官方文档示意图:

📌 这个回调只告诉你"现在滚到哪里了",并不会告诉你"用户什么时候停下来"

所以核心问题变成了:怎么自己识别"用户停手了"?

业界主流方案有两种:

  • 节流(throttle):滚动过程中反复触发,但保证每隔 N ms 至少执行一次。
  • 防抖(debounce):等用户停止操作 N ms 后才触发一次。

我们要的恰好是防抖的语义——“停下来再显示”。所以基本思路就清晰了:

每次滚动先把区域藏起来,并清掉之前的定时器、开一个新的定时器;定时器在 N ms 后执行"显示"动作。因为只有真正停下来时定时器才不会被清掉,所以定时器触发的那一刻,就是用户停手的时刻。

三、代码实现

下面把 axml、js 一次给全,方便直接照着抄。

3.1 模板(axml)

只需要用a:if把这块区域包起来,控制显示与隐藏即可:

<!-- pages/demo/index.axml --><viewclass="page"><!-- 页面正文 --><viewclass="content">...</view><!-- 底部订阅提示区域 --><viewclass="subscribe-remind"a:if="{{subscribeRemindVisible}}"><text>打开通知,第一时间收到新内容</text></view></view>

对应的 acss(可选):

.subscribe-remind{position:fixed;left:0;right:0;bottom:0;padding:20rpx 32rpx;background:#ffffff;box-shadow:0 -4rpx 12rpxrgba(0,0,0,0.06);}

3.2 原作者的原始实现(js)

data 里准备三个状态:

Page({data:{subscribeRemindVisible:true,// 是否展示底部区域(布尔值)isScrolling:false,// 标记是否处于滚动中timer:null,// 定时器句柄},onPageScroll(){// 正在滚动 → 立刻隐藏区域,并把"滚动中"标记置为 truethis.setData({subscribeRemindVisible:false,isScrolling:true,});// 清掉上一轮可能还没执行的定时器if(this.data.timer){clearInterval(this.data.timer);}// 起一个 100ms 的轮询定时器this.data.timer=setInterval(()=>{// 第一次执行(100ms):把标记清回 false// 第二次执行(200ms):若标记依然为 false,说明这段时间没有新的 onPageScroll,// 即用户真的停了 → 显示区域if(!this.data.isScrolling){clearInterval(this.data.timer);this.setData({subscribeRemindVisible:true});}// 每次 tick 末尾都重置标记,给下一次比较用this.setData({isScrolling:false});},100);},});

这段代码的核心思路就是**“两段式轮询”**:

  • 第 100ms 那个 tick:把isScrolling置成false
  • 第 200ms 那个 tick:如果isScrolling还是false(中间没有新事件进来),就显示区域。

只有真正停下来时,定时器才能跨过这两轮、把区域显示出来。

⚠️ 这版写法能 work,但有两个不优雅的地方:

  1. 每 100ms 都执行一次setData({ isScrolling: false }),会反复触发脏检查和渲染,开销偏大;
  2. isScrolling其实只是个内部标记,没必要塞进data,挂在this上就好。

下面给一版等价的、更干净的实现,推荐直接用这版。

3.3 推荐实现(更干净的等价写法)

Page({data:{subscribeRemindVisible:true,},onPageScroll(){// 滚动中:先清掉旧定时器,把区域藏起来if(this._tipTimer)clearTimeout(this._tipTimer);this.setData({subscribeRemindVisible:false});// 等用户停手 200ms 后再把区域展开// 注意:句柄挂在 this 上即可,不要写进 data,避免多余渲染this._tipTimer=setTimeout(()=>{this.setData({subscribeRemindVisible:true});this._tipTimer=null;},200);},});

思路完全一样——“滚动 → 清定时器 + 隐藏 → 重新起一个定时器,停 N ms 后再显示”——但好处很明显:

  • 只用了一个setTimeout,没有isScrolling中间态,可读性更高;
  • 定时器句柄挂在this._tipTimer,不进 data,不会触发额外渲染
  • 状态变更只有"显示 / 隐藏"两种,对外接口更稳定。

四、几个容易踩的坑

  1. onPageScroll触发频率非常高。实测滚动一次屏幕会触发几十到上百次,千万不要在里面做重活(请求、复杂计算)。本文的方案里只做clearTimeout+setData一个布尔值,是安全的。
  2. 别用setInterval,用setTimeoutsetInterval一旦开启就会一直执行,需要手动清除;setTimeout触发一次就结束,跟"停手再显示"的语义更吻合。
  3. 停顿时间 100~200ms 比较合适。太短会把"滑动中短暂的停顿"误判为停止;太长会让用户觉得"卡"。
  4. data 里别存太多中间态isScrolling只是个标记,没必要存进 data(不进 data 就不会触发脏检查,渲染更轻)。上面"推荐实现"里就直接挂在this上。

五、小结

整个需求拆开来看就三步:

  • onPageScroll触发即隐藏—— 监听滚动;
  • 滚动时清掉旧的setTimeout,起一个新的—— 防抖;
  • 新定时器到点了再显示—— 识别停手。

代码总共不到 20 行,关键是想清楚"什么时刻才算停手"——它就是"定时器能跑完"的那一刻。所有没有提供scrollEnd事件的小程序/Web 容器,都可以用这个套路解决。


如果本文对你有帮助,欢迎点赞 / 收藏 / 评论三连支持一下~有更好的实现方案也欢迎留言交流 🙌

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/7 3:53:51

【单片机毕业设计】基于 STM32 的智能充电桩控制系统设计与实现, 基于单片机的刷卡计费式充电桩智能监测系统(017001)

文章目录20 个相关毕业设计备选题目项目研究背景摘要总体方案一、核心硬件设备清单及选型说明二、硬件整体架构逻辑核心功能一、基础交互功能二、射频卡身份认证核心功能三、充电桩硬件检测与状态指示功能四、闸机机械控制功能五、语音播报辅助交互功能六、计费与账单统计核心功…

作者头像 李华
网站建设 2026/7/7 3:53:49

2026年AI写量化策略,先补规则和流程完整性

当已有量化经验的人开始使用 AI 辅助开发&#xff0c;最容易被放大的不是速度&#xff0c;而是前期表达中的含糊。策略规则没有说清&#xff0c;流程节点没有排顺&#xff0c;AI 仍然可能给出一段看似能用的代码&#xff1b;问题是&#xff0c;使用者之后很难知道它到底偏离了哪…

作者头像 李华
网站建设 2026/7/7 3:53:33

TPS5450 降压变换器 PCB 布局实战:3 个关键回路面积控制与 20% 纹波优化

TPS5450 降压变换器 PCB 布局实战&#xff1a;3 个关键回路面积控制与 20% 纹波优化 在电源硬件设计中&#xff0c;PCB 布局往往是决定系统性能的关键因素。一个优秀的降压变换器设计&#xff0c;即使原理图完美无缺&#xff0c;也可能因为布局不当导致效率下降、EMI 超标或输出…

作者头像 李华
网站建设 2026/7/7 3:48:06

直播+私域系统源码如何结合AI数字人实现智能直播?

近年来&#xff0c;AI大模型、数字人技术和实时音视频技术快速发展&#xff0c;直播行业也迎来了新的升级方向。从最初的真人直播&#xff0c;到如今的AI数字人直播&#xff0c;越来越多的企业开始尝试利用AI数字人降低直播成本、提升直播效率&#xff0c;实现724小时持续直播。…

作者头像 李华
网站建设 2026/7/7 3:45:35

短剧剧本采购怎么避坑?从行业视角拆解渠道选择逻辑

引言国内短剧产业经过多轮规范化调整&#xff0c;内容生产标准、版权监管规则持续完善&#xff0c;真人拍摄、AIGC 虚拟影像、海外内容输出三条业务线并行发展&#xff0c;市场里可供选择的剧本渠道数量持续增多。对于制作团队而言&#xff0c;短剧剧本采购是项目启动的核心环节…

作者头像 李华
网站建设 2026/7/7 3:45:10

OBS Face Tracker:基于计算机视觉的实时面部追踪技术深度解析

OBS Face Tracker&#xff1a;基于计算机视觉的实时面部追踪技术深度解析 【免费下载链接】obs-face-tracker Face tracking plugin for OBS Studio 项目地址: https://gitcode.com/gh_mirrors/ob/obs-face-tracker 技术架构与实现原理 OBS Face Tracker作为OBS Studio…

作者头像 李华