效果图

既然来了,把妹子都给你。

定义

懒加载,前端人都知道的一种性能优化方式,简单的来说,只有当图片出现在浏览器的可视区域内时,才设置图片正真的路径,让图片显示出来。这就是图片懒加载。

实现原理

监听页面的scroll事件,判读元素距离页面的top值是否是小于等于页面的可视高度

判断逻辑代码如下

element.getBoundingClientRect().top <= document.documentElement.clientHeight ? 显示 : 默认

我们知道小程序页面的脚本逻辑是在JsCore中运行,JsCore是一个没有窗口对象的环境,所以不能在脚本中使用window,也无法在脚本中操作组件。

所以关于图片懒加载就需要在数据上面做文章了。

页面

页面上面只需要根据数据的某一个字段来判断是否显示图片就可以了,字段为Boolean类型,当为false的时候显示默认图片就行了。

代码大概长成这样

<view wx:for="{{list}}" class='item item-{{index}}'wx:key="{{index}}"><image class="{{item.show ? 'active': ''}}" src="{{item.show ? item.src : item.def}}"></image>
</view>
复制代码

布局跟简单,view组件里面有个图片,并循环list,有多少就展示多少

image组件的src字段通过每一项的show来进行绑定,active是加了个透明的过渡

样式

image{transition: all .3s ease;opacity: 0;
}
.active{opacity: 1;
}复制代码

逻辑

本位主要讲解懒加载,所以把数据写死在页面上了

数据结构如下:

我们使用两种方式来实现懒加载,准备好没有,一起来快乐的撸码吧。

WXML节点信息

小程序支持调用createSelectQuery创建一个SelectorQuery实例,并使用select方法来选择节点,并通过boundingClientRect来获取节点信息。

wx.createSelectorQuery().select('.item').boundingClientRect((ret)=>{console.log(ret)
}).exec()复制代码

显示结果如下

悄悄告诉你,小程序里面有个onPageScroll函数,是用来监听页面的滚动的。 还有个getSystemInfo函数,可以获取获取系统信息,里面包含屏幕的高度。

接下来,思路就透彻了吧。还是上面的逻辑, 扒拉扒拉直接写代码就行了,这里只写下主要的逻辑,完整代码请戳文末github

showImg(){let group = this.data.grouplet height = this.data.height  // 页面的可视高度wx.createSelectorQuery().selectAll('.item').boundingClientRect((ret) => {ret.forEach((item, index) => {if (item.top <= height) { 判断是否在显示范围内group[index].show = true // 根据下标改变状态}})this.setData({group})}).exec()}
onPageScroll(){ // 滚动事件this.showImg()
}
复制代码

至此,我们完成了一个小程序版的图片懒加载,只是思维转变了下,其实并没有改变实现方式。我们来学些新的东西吧。

节点布局相交状态

节点相交状态是啥?它是一个新的API,叫做IntersectionObserver, 本文只讲解简单的使用,了解更多请猛戳没错,就是点我

小程序里面给它的定义是节点布局交叉状态API可用于监听两个或多个组件节点在布局位置上的相交状态。这一组API常常可以用于推断某些节点是否可以被用户看见、有多大比例可以被用户看见。

里面设计的概念主要有五个,分别为

  • 参照节点:以某参照节点的布局区域作为参照区域,参照节点可以有多个,多个话参照区域取它们的布局区域的交集
  • 目标节点:监听的目标,只能是一个节点
  • 相交区域:目标节点与参照节点的相交区域
  • 相交比例:目标节点与参照节点的相交比例
  • 阈值:可以有多个,默认为[0], 可以理解为交叉比例,例如[0.2, 0.5]

关于它的API有五个,依次如下

1、createIntersectionObserver([this], [options]),见名知意,创建一个IntersectionObserver实例

2、intersectionObserver.relativeTo(selector, [margins]), 指定节点作为参照区域,margins参数可以放大缩小参照区域,可以包含top、left、bottom、right四项

3、intersectionObserver.relativeToViewport([margin]),指定页面显示区域为参照区域

4、intersectionObserver.observer(targetSelector, callback),参数为指定监听的节点和一个回调函数,目标元素的相交状态发生变化时就会触发此函数,callback函数包含一个result,下面再讲

5、intersectionObserver.disconnect() 停止监听,回调函数不会再触发

然后说下callback函数中的result,它包含的字段为

字段名 类型 说明
intersectionRatio Number 相交比例
intersectionRect Object 相交区域的边界,包含 left 、 right 、 top 、 bottom 四项
boundingClientRect Object 目标节点布局区域的边界,包含 left 、 right 、 top 、 bottom 四项
relativeRect Object 参照区域的边界,包含 left 、 right 、 top 、 bottom 四项
time Number 相交检测时的时间戳

我们主要使用intersectionRatio进行判断,当它大于0时说明是相交的也就是可见的。

先来波测试题,请说出下面的函数做了什么,并且log函数会执行几次

1、
wx.createIntersectionObserver().relativeToViewport().observer('.box', (result) => {console.log('监听box组件触发的函数')   })2、
wx.createIntersectionObserver().relativeTo('.box').observer('.item', (result) => {console.log('监听item组件触发的函数')
})3、
wx.createIntersectionObserver().relativeToViewport().observer('.box', (result) => {if(result.intersectionRatio > 0){console.log('.box组件是可见的') }
})
复制代码

duang,揭晓答案。

第一个以当前页面的视窗监听了.box组件,log会触发两次,一次是进入页面一次是离开页面

第二个以.box节点的布局区域监听了.item组件,log会触发两次,一次是进入页面一次是离开页面

第三个以当前页面的视窗监听了.box组件,log只会在节点可见的时候触发

好了,题也做了,API你也掌握了,相信你已经可以使用IntersectionObserver来实现图片懒加载了吧,主要逻辑如下

let group = this.data.group // 获取图片数组数据
for (let i in this.data.group){   wx.createIntersectionObserver().relativeToViewport().observe('.item-'+ i, (ret) => {if (ret.intersectionRatio > 0){group[i].show = true }this.setData({group})})
}
复制代码

最后

至此,我们使用两种方式实现了小程序版本的图片懒加载,可以发现,使用IntersectionObserver来实现不要太酸爽。

本文代码请戳github

小程序之图片懒加载[完美方案,你不来看看?]相关推荐

  1. 微信小程序之图片懒加载

    数据都是死的,复制即可查看效果 实现原理: 通过onPageScroll() 方法返回的e.scrollTop值与手机窗口宽高进行计算,较完美的解决了等高或均高图片序列的图片懒加载. 关于图片高度:图 ...

  2. 小程序图片懒加载放在服务器,【小程序】使用uni-app搭建小程序环境---图片懒加载...

    延迟加载的理念:页面初始化时,暂不加载处于屏幕可见区域之外的图片.该方案会有如下几大好处:\n加快页面渲染速度 \n提升页面滚动性能 \n默认不下载屏幕外的图片,减少网络流量 主标题 列表二级标题 e ...

  3. [html] 举例说明图片懒加载的方案有哪些?

    [html] 举例说明图片懒加载的方案有哪些? 利用 getBoundingClientRect() 这个 API 获取图片元素相对于视口的位置,来判断是否需要加载图片利用 IntersectionO ...

  4. 小程序实现图片预加载(图片延迟加载)

    这几天搞百度小程序,对接的网站需要展示大量图片,并且图片都是高清图片,因为要同步支持pc和手机站,在开发者工具中测试的时候,图片都是瞬间加载,因此感觉不出什么,但是真机预览的时候,特别是4G情况下,会 ...

  5. 微信 html自动加载js,微信小程序实现图片预加载组件

    网页中的图片预加载 图片预加载对图片画廊及图片占据很大比例的网站来说十分有利,它保证了图片快速.无缝地发布,也可帮助用户在浏览你网站内容时获得更好的用户体验.我们知道在 Web 页面中实现图片的预加载 ...

  6. 小程序本地图片偶尔加载不出来_小程序优化的20中策略

    体验评分是一项给小程序的体验好坏打分的功能,它会在小程序运行过程中实时检查,分析出一些可能导致体验不好的地方,并且定位出哪里有问题,以及给出一些优化建议. 使用流程: 1.打开开发者工具,在详情里切换 ...

  7. 微信小程序优化:如何实现图片懒加载?

    前言 当我们在使用微信小程序浏览图片时,不可避免地会遇到加载缓慢的情况.这不仅会影响用户体验,还会耗费用户的流量.那么,有没有一种方法可以让图片在用户需要时再进行加载,从而提升用户体验和减少流量消耗呢 ...

  8. 微信小程序image图无法加载出来的解决办法(亲测有效)

    在微信小程序中,第一次加载页面时图片(线上图)加载不出来/图片灰色背景显示,这个时候该如何解决这个问题呢?请带着问题查看这篇博客,希望对您有所帮助(点赞skr) 看官方文档? 自行解决? 写在前面(初 ...

  9. 小程序图片懒加载较完美解决方案

    无需考虑数据结构,效果如图 话不多说,先上代码 wxml <view class="content"><block wx:key="{{img}}&qu ...

最新文章

  1. 2012年上海市高等学校计算机等级考试试卷,2012年上海市高等学校计算机等级考试A试卷...
  2. 服务器带系统,服务器有带系统的吗
  3. mitmproxy抓包 | Python篡改请求参数实战(五)
  4. 有没有什么好的C++视频教程?
  5. 微软“.Net社区虚拟大会”dotnetConf2015:关键词:.NET 创新、开源、跨平台
  6. python产生随机数列表_python如何产生10个不同的随机数
  7. CleanMyMac X 4.9 for Mac电脑清理软件 中文语言免费版
  8. 阶段1 语言基础+高级_1-3-Java语言高级_05-异常与多线程_第3节 线程同步机制_4_解决线程安全问题_同步代码块...
  9. html初识教学反思,五年级长方体的认识教学反思
  10. 3D 世界的钥匙「GitHub 热点速览 v.22.08」
  11. 【支付】银行卡收单业务
  12. C语言输入10名同学3门课,输入10个学生3门课的成绩,统计各科全部及格的人数(c语音)...
  13. 车辆调度系统php,GitHub - Teamo1001/VehicleSYS: 一个基于Laravel框架的车辆调度、定位、管理系统,服务端...
  14. “当高启强遇到陈书婷”与TCP协议
  15. excel条形图-蝴蝶图的画法
  16. MATLAB之Nyquist图和Bode图
  17. 冯诺依曼计算机体系结构
  18. 小程序触发刷新页面的方法
  19. Vulhub漏洞靶场搭建
  20. 利用FFT分析比较卡尔曼滤波算法、低通滤波算法、滑动平均滤波的频谱

热门文章

  1. mysql 线程池源码模块_易语言Mysql线程池2.0模块源码
  2. linux进程故障如何修复,33.Linux开机过程及启动故障修复
  3. angular五大服务顺序_建议收藏 | 一篇文章告诉你工种的进场顺序
  4. matlab训练神经网络模型并导入simulink详细步骤
  5. 控制显示隐藏_iOS13隐藏了5个超实用新功能:让iPhone的使用体验更好
  6. numpy.random.uniform()
  7. solaris与linux区别,solaris与linux命令的区别
  8. matlab ac电源,基于MATLAB对AC/DC/AC电源的死区效应的谐波分析及仿真
  9. Mybatis学习之配置优化
  10. python close_wait_线上大量CLOSE_WAIT原因深入分析