taro小程序添加骨架屏的实现代码


Posted in Javascript onNovember 15, 2019

最近做了一些小程序方面的性能优化,如分包加载,添加骨架屏等,这次主要说一下骨架屏的相关内容。

关于骨架屏,有三种方法:

1.直接请UI同学帮忙P张图,当做loading图放上去。这种方法简单粗暴,但是需要请人帮忙~
2.根据每个页面,自己写一套相同的代码来覆盖样式。这种方法的工程量,你懂的~
3.能不能写个组件呢?该组件自动获取元素位置大小信息来渲染,数据返回后将其卸载。

下面主要说第三种方法~

主框架采用taro,一套代码兼容多端,但是今天这个代码,需要考虑兼容性~

根据上面的思路,我们首先要找到骨架屏的容器,然后找到需要P成灰色的元素,获取该元素的位置大小信息,最后就是渲染了~

获取元素,taro提供了API,Taro.createSelectorQuery()。通过这个API返回一个SelectorQuery对象实例,然后再通过selectAll()来查找骨架中带有特定类的class名,查找之后通过boundingClientRect()获取元素的位置大小信息,把这些信息存放在数组中。
我这边写了两个类,一个是skeleton-radius,渲染圆形;一个是skeleton-rect,渲染长方形。后续大家可以自行扩展。

文字有点多,大家可能看着有点云里雾里的,下面上代码~

// 百度小程序目前不支持跨自定义组件的后代选择器: >>>
  // 但是H5使用后代选择器(.the-ancestor .the-descendant)的时候,可以自动识别自定义组件内的后代
  // 微信小程序支持跨自定义组件都后代选择器(.the-ancestor >>> .the-descendant),可修改为如`.${this.props.selector} >>> .${this.props.selector}-radius`
  if (process.env.TARO_ENV === 'weapp') {
    Taro.createSelectorQuery().selectAll(`.${this.props.selector} >>> .${this.props.selector}-radius`)
      .boundingClientRect().exec(rect => {
        that.setState({
          radiusList: rect[0]
        });
      });
  }
  else {
    Taro.createSelectorQuery().selectAll(`.${this.props.selector} .${this.props.selector}-radius`)
    .boundingClientRect().exec(rect => {
      that.setState({
        radiusList: rect[0]
      });
    });
  }

大家也看到上面的注释了,如果要在多端运行,可先判断环境,根据环境使用不同的选择器。上面代码是实现一个圆形的灰色区域~大家如果有多个形状的需求的话,可以简单封装一个函数,这里我就不再细说了,具体的可以到Demo详细查看~
细说一下后代选择器的兼容性问题:

  1. 百度小程序目前不支持跨自定义组件的后代选择器: >>>。
  2. 但是H5使用后代选择器(.the-ancestor .the-descendant)的时候,可以自动识别自定义组件内的后代。使用自定义组件时,外层是否有元素包裹,都可识别到自定义组件内部的指定类选择器。
  3. 微信小程序支持跨自定义组件的后代选择器(.the-ancestor >>> .the-descendant),但使用自定义组件时,外层不能嵌套元素,否则无法识别。

接下来就是渲染了,这个比较简单,直接上代码~这里背景色和将要P成条状等的元素的背景色都可以在使用组件时自定义传入,也可以不传,有默认色~

<View className='skeleton-container' style={{background: `${bgColor}`}}>
      {
        radiusList.map(radiusItem => (
          <View className='skeleton-item skeleton-item-radius' style={{width: `${radiusItem.width}PX`, height: `${radiusItem.height}PX`,
            background: `${itemColor}`, top: `${radiusItem.top}PX`, left: `${radiusItem.left}PX`}}
          />
        ))
      }
      {
        rectList.map(rectItem => (
          <View className='skeleton-item' style={{width: `${rectItem.width}PX`, height: `${rectItem.height}PX`,
            background: `${itemColor}`, top: `${rectItem.top}PX`, left: `${rectItem.left}PX`}}
          />
        ))
      }
    </View>

到这里,组件已经完成了,使用的时候可以直接引入组件,然后传入selector就可以了,注意,由于数据是动态获取的,页面开始为空,这里就需要mock一些假数据来填充页面了~要覆盖的元素类名必须和组件中的图形类保持一致~

<View className='container' style={{fontSize: '20PX'}}>
      {
        showSkeleton && <Skeleton
          selector='skeleton'
          bgColor='pink'
          itemColor='skyblue'
        />
      }
      <View className='skeleton'>
        <View className='userInfo'>
          <Image
            src={userInfo.avatarUrl}
            alt='用户头像'
            className='userInfo-avatar skeleton-radius'
          />
          <Text>{userInfo.nickName}</Text>
        </View>
        <View>
          {
            list.map(item => (
              <View className='skeleton-rect' style={{marginBottom: '30PX'}}>{item}</View>
            ))
          }
        </View>
        {/* 自定义组件外层最好没有元素包裹,否则微信小程序无法识别,但是H5可以识别 */}
        <List />
      </View>
    </View>

看到注释了吗?使用自定义组件时一定要注意噢~自定义组件若被元素报错,微信小程序无法识别到自定义组件内的图形类!!!

最后要说一下适合使用骨架屏的场景:页面结构简单,元素的宽高固定~若元素宽高不固定的话,你写的mock假数据可能和实际渲染出来的页面差距较大,例如瀑布流~

好了,这次的一些收获就到这里了~大家如果有更好的方法,可以留言交流~最后,附上完整的代码地址~

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
js判断浏览器的比较全的代码
Feb 13 Javascript
Jquery插件之打造自定义的select标签
Nov 30 Javascript
自定义右键属性覆盖浏览器默认右键行为实现代码
Feb 02 Javascript
Struts2的s:radio标签使用及用jquery添加change事件
Apr 08 Javascript
Knockout visible绑定使用方法
Nov 15 Javascript
js根据日期判断星座的示例代码
Jan 23 Javascript
基于js实现投票的实例代码
Aug 04 Javascript
基于vue的fullpage.js单页滚动插件
Mar 20 Javascript
详解react-router4 异步加载路由两种方法
Sep 12 Javascript
react redux入门示例
Apr 19 Javascript
详解create-react-app 2.0版本如何启用装饰器语法
Oct 23 Javascript
原生js实现日历效果
Mar 02 Javascript
详解Angular Karma测试的持续集成实践
Nov 15 #Javascript
Javascript 类型转换、封闭函数及常见内置对象操作示例
Nov 15 #Javascript
JavaScript定时器常见用法实例分析
Nov 15 #Javascript
解决Layui 表格自适应高度的问题
Nov 15 #Javascript
layui前端时间戳转化实例
Nov 15 #Javascript
JavaScript变量基本使用方法实例分析
Nov 15 #Javascript
JavaScript字符串处理常见操作方法小结
Nov 15 #Javascript
You might like
php简单封装了一些常用JS操作
2007/02/25 PHP
PHP开发中的错误收集,不定期更新。
2011/02/03 PHP
php批量缩放图片的代码[ini参数控制]
2011/02/11 PHP
php 不使用js实现页面跳转
2014/02/11 PHP
CMS中PHP判断系统是否已经安装的方法示例
2014/07/26 PHP
分享一个Laravel好用的Cache宏
2015/03/02 PHP
学习php设计模式 php实现合成模式(composite)
2015/12/08 PHP
php微信公众平台开发之微信群发信息
2016/09/13 PHP
laravel中的一些简单实用功能
2018/11/03 PHP
基于Jquery制作的幻灯片图集效果打包下载
2011/02/12 Javascript
javascript 图片裁剪技巧解读
2012/11/15 Javascript
使用Sticker.js实现贴纸效果
2015/01/28 Javascript
jQuery关键词说明插件cluetip使用指南
2015/04/21 Javascript
JavaScript通过事件代理高亮显示表格行的方法
2015/05/27 Javascript
nodejs实现bigpipe异步加载页面方案
2016/01/26 NodeJs
浅谈JS之tagNaem和nodeName
2016/09/13 Javascript
微信小程序实现折叠面板
2018/01/31 Javascript
babel的使用及安装配置教程
2018/02/22 Javascript
基于jquery实现左右上下移动效果
2018/05/02 jQuery
vue-cli项目根据线上环境分别打出测试包和生产包
2018/05/23 Javascript
解决Js先触发失去焦点事件再执行点击事件的问题
2018/08/30 Javascript
Vue自定义render统一项目组弹框功能
2020/06/07 Javascript
[29:59]完美世界DOTA2联赛PWL S3 Forest vs access 第二场 12.11
2020/12/13 DOTA
对Python 窗体(tkinter)文本编辑器(Text)详解
2018/10/11 Python
python中将两组数据放在一起按照某一固定顺序shuffle的实例
2019/07/15 Python
Pandas 重塑(stack)和轴向旋转(pivot)的实现
2019/07/22 Python
Python爬虫爬取煎蛋网图片代码实例
2019/12/16 Python
jupyter 中文乱码设置编码格式 避免控制台输出的解决
2020/04/20 Python
六一儿童节演讲稿
2014/05/23 职场文书
打架检讨书
2015/01/27 职场文书
幼儿教师小班个人总结
2015/02/05 职场文书
个人简历求职信范文
2015/03/20 职场文书
刮痧观后感
2015/06/05 职场文书
安全温馨提示语大全
2015/07/14 职场文书
z-index不起作用
2021/03/31 HTML / CSS
利用Python第三方库实现预测NBA比赛结果
2021/06/21 Python