如何在支付宝小程序内实现骨架屏效果

简介: 支付宝小程序骨架屏实现方案。
首先了解下什么是骨架屏?

骨架屏就是在页面数据尚未加载前先给用户展示出页面的大致结构,直到请求数据返回后再渲染页面,补充进需要显示的数据内容。常用于文章列表、动态列表页等相对比较规则的列表页面。 很多项目中都有应用饿了么h5版本,知乎,facebook等网站中都有应用。
以下图举例,常用饿了么的童鞋,应该看到过饿了么的这个首页预加载图的效果:
饿了么h5实现方案
5116580-c56909e9f9fdcb2a.png

咱们来聊聊小程序的实现方案:
1.最简单最快捷最暴力的,直接让设计一张图片盖上去,当loading使用。

举例:饿了么的订单页面,查看了下源码,是使用的SVG的图
5116580-989596ea5bd010db.png

2.前端使用view写死一套数据(缺点很明显,假如页面布局有修改的话,那么除了修改业务代码之外还需要额外修改骨架屏,增加了维护的成本)

举例:简单写了个微信小程序的代码片段(支付宝暂无代码片段功能):https://developers.weixin.qq.com/s/ZAuYzHmX7ObC
5116580-87a4a9e4aaa91d8d.png

3.页面Data里写死一套默认数据,使用小程序的my.createSelectorQuery().selectAll 选择了所有要渲染的矩形和圆形节点,在页面中,使用循环,遍历出所有的节点,再加上样式。
基本原理就是
  • 在组件初始化时,设置其绝对定位,大小为整个屏幕大小
  • 然后用节点查询方法,找到类名等于skeletons的元素,并设置组件的背景的位置及大小和元素的一致,覆盖这个元素。
  • 用节点查询方法,找到所有的类名等于skeletons-circle 元素,并将它们的位置及大小信息加入到skeletons-circle-Arr数组中,在axml中用a:for循环渲染出来(也是绝对定位)
  • 用节点查询方法,找到所有的类名等于skeletons-rect 元素,并将它们的位置及大小信息加入到skeletons-rect-Arr数组中,在axml中用a:for循环渲染出来(也是绝对定位)

当然啦,这里还有一些判断,还可以设置屏幕上提示是旋转小圈圈还是背景色渐变提醒等,都是一些比较细节的东西,就不细说。

那么到这就完了吗?当然木有,现在说下最后一种方案(目前我们小程序正在使用的方案)。

4. 如何更好的把骨架屏代码嵌入到业务里面,是否可以在接口请求成功后,先渲染出一套接口返回的数据匹配的骨架,再展示给用户看呢,减少用户查看白屏(loading)时间。(缺点是如果请求挂掉,骨架屏是不会渲染出来的)

这是我们线上版本效果示例图:
骨架屏示意图.jpg

首先来看 如何操作:
使用my.createSelectorQuery 获取到相关节点进行渲染操作,但是我们把默认数据这一栏更改为动态数据。
核心代码就是自定义组件内抛出的isNodes和isComplete属性

//axml
<skeletons isNodes="{{isNodes}}" isComplete="{{isComplete}}"" />
//页面节点上需要手动添加一个样式类。
比如轮播图 宽686rpx,高140rox,是长方形那么给他的样式上加上‘skeletions-rect’,如果是圆形给他加上‘skeletons-circle’
业务内代码如下:
<!-- 轮播图组件 -->
  <block a:if="{{swiperData.length > 0}}">
    <swiper class="swiperSlide" indicator-dots="{{indicatorDots}}" indicator-color="#ccc" indicator-active-color="#00CC88" autoplay circular>
      <block a:for="{{swiperData}}" a:key="{{index}}">
        <swiper-item>
          <view class="swiper-item">
            <image lazy-load src="{{item.image}}" data-index="{{index}}" onTap="universalJump" class="skeletons-rect" />
          </view>
        </swiper-item>
      </block>
    </swiper>
    <!-- <qts-swiper resourseFrom="{{swiperData}}" indicatorDots="{{indicatorDots}}"></qts-swiper> -->
  </block>
相关JS如下:
  initData() {
    let postData = {
        townId: util.getStorageSync('townId') || 87
    }
    // 初始化请求第一个接口
    app.postAjax('https://url.com', postData).then((res) => {
      if (res.success) {
        this.setData({
          bodyData: res.data,  //页面展示数据的大对象
          isNodes: true //抓取节点绘制骨架屏
        }, () => {
          this.setData({
            isComplete: true  //节点绘制完成,隐藏骨架屏
          })
        })
      } else {
        util.toast(res.msg || '团团开小差啦,请稍后重试')
      }
    }, () => {
      util.toast('团团开小差啦,请稍后重试')
    })
  },

在微信端的难题:组件之间无法样式穿透的问题(A组件通过index页面影响B组件的样式),在支付宝端完美不存在,算是解决了一个大问题吧。
最后完整组件代码地址:https://gitee.com/minchangyong/skeletons

具体效果可以微信、支付宝搜索《青团社兼职》小程序查看。

相关文章
|
6月前
|
小程序 安全 物联网
【经验分享】支付宝小程序常用appId
【经验分享】支付宝小程序常用appId
1949 6
|
6月前
|
小程序 JavaScript Android开发
【经验分享】如何在支付宝小程序里玩转富文本功能
【经验分享】如何在支付宝小程序里玩转富文本功能
289 6
|
6月前
|
小程序 Devops 开发工具
支付宝小程序入门学习之一:如何创建支付宝小程序并在手机上预览
支付宝小程序入门学习之一:如何创建支付宝小程序并在手机上预览
|
5月前
|
小程序 前端开发 Java
(JAVA)支付宝小程序登录相关(authToken获取用户唯一userId、encryptedData解密手机号)
(JAVA)支付宝小程序登录相关(authToken获取用户唯一userId、encryptedData解密手机号)
366 0
|
6月前
|
小程序 IDE 开发工具
社区每周丨预授权支付新增线下场景及支付宝小程序开发者大赛启动(9.4-9.8)
社区每周丨预授权支付新增线下场景及支付宝小程序开发者大赛启动(9.4-9.8)
83 11
|
6月前
|
移动开发 小程序 API
【每周一个小技巧】支付宝小程序内如何跳转生活号文章
【每周一个小技巧】支付宝小程序内如何跳转生活号文章
252 6
|
6月前
|
小程序 JavaScript 前端开发
【每周一个小技巧】支付宝小程序跳转生活号的几种方式
【每周一个小技巧】支付宝小程序跳转生活号的几种方式
124 7
|
6月前
|
小程序 前端开发 IDE
【经验分享】支付宝小程序订阅消息功能实操(前端篇)|江海计划
【经验分享】支付宝小程序订阅消息功能实操(前端篇)|江海计划
679 7
|
6月前
|
小程序 开发者
【经验分享】支付宝小程序如何获取外部链接携带的参数
【经验分享】支付宝小程序如何获取外部链接携带的参数
316 7
|
6月前
|
移动开发 小程序 JavaScript
【经验分享】记一次支付宝小程序的性能优化
【经验分享】记一次支付宝小程序的性能优化
114 6