谈谈IntersectionObserver懒加载的具体使用


Posted in Javascript onOctober 15, 2019

概念

IntersectionObserver接口(从属于Intersection Observer API)为开发者提供了一种可以异步监听目标元素与其祖先或视窗(viewport)交叉状态的手段。祖先元素与视窗(viewport)被称为根(root)。

这是MDN上给的官方概念,不用去管它,我粘出来只是为了显得专业点嘛...

重点看这里 监听目标元素与其祖先或视窗交叉状态的手段 ,其实就是观察一个元素是否在视窗可见。

谈谈IntersectionObserver懒加载的具体使用

可以看到,交叉了就是说明当前元素在视窗里,当前就是可见的了。

API

var io = new IntersectionObserver(callback, options)

其实就是一个简单的构造函数。

以上代码会返回一个 IntersectionObserver 实例, callback 是当元素的可见性变化时候的回调函数, options 是一些配置项(可选)。

我们使用返回的这个实例来进行一些操作。

io.observe(document.querySelector('img')) 开始观察,接受一个DOM节点对象
io.unobserve(element) 停止观察 接受一个element元素
io.disconnect() 关闭观察器

options

root

用于观察的根元素,默认是浏览器的视口,也可以指定具体元素,指定元素的时候用于观察的元素必须是指定元素的子元素

threshold

用来指定交叉比例,决定什么时候触发回调函数,是一个数组,默认是 [0]

const options = {
	root: null,
	threshold: [0, 0.5, 1]
}
var io = new IntersectionObserver(callback, options)
io.observe(document.querySelector('img'))

上面代码,我们指定了交叉比例为0,0.5,1,当观察元素img0%、50%、100%时候就会触发回调函数

rootMargin

用来扩大或者缩小视窗的的大小,使用css的定义方法, 10px 10px 30px 20px 表示top、right、bottom 和 left的值

const options = {
	root: document.querySelector('.box'),
	threshold: [0, 0.5, 1],
	rootMargin: '30px 100px 20px'
}

为了方便理解,我画了张图,如下

谈谈IntersectionObserver懒加载的具体使用

首先我们来看下图上的问题,蓝线是什么呢?他就是咱们定义的root元素,我们添加了 rootMargin 属性,将视窗的增大了,虚线就是现在的视窗,所以元素现在也就在视窗里面了。

由此可见,root元素只有在 rootMargin 为空的时候才是绝对的视窗。

说了简单的options,接下来我们看下 callback

callback

上面我们说到,当元素的可见性变化时,就会触发callback函数。

callback函数会触发两次,元素进入视窗(开始可见时)和元素离开视窗(开始不可见时)都会触发

var io = new IntersectionObserver((entries)=>{
	console.log(entries)
})

io.observe($0)

以上代码,请在chrome控制台进行调试,这里我使用了 $0 选择了上一次我审查元素的选择的节点

运行结果如下

谈谈IntersectionObserver懒加载的具体使用

我们可以看到callback函数有个 entries 参数,它是个 IntersectionObserverEntry 对象数组,接下来我们重点说下IntersectionObserverEntry对象

IntersectionObserverEntry

IntersectionObserverEntry 提供观察元素的信息,有七个属性。

boundingClientRect 目标元素的矩形信息 intersectionRatio 相交区域和目标元素的比例值 intersectionRect/boundingClientRect 不可见时小于等于0 intersectionRect 目标元素和视窗(根)相交的矩形信息 可以称为相交区域 isIntersecting 目标元素当前是否可见 Boolean值 可见为true rootBounds 根元素的矩形信息,没有指定根元素就是当前视窗的矩形信息 target 观察的目标元素 time 返回一个记录从 IntersectionObserver 的时间到交叉被触发的时间的时间戳

上面几个矩形信息的关系如下

谈谈IntersectionObserver懒加载的具体使用

划重点

intersectionRatio和 isIntersecting 是用来判断元素是否可见的,押题咯...

懒加载

好了,通过上面一些概念我们大概了解了 IntersectionObserver 是个什么东西,接下来我们用它来写点代码,写什么呢?没错就是懒加载。

通过IntersectionObserver来实现懒加载,就简单的多了,我们只需要设置回调,判断当前元素是否可见,再进行渲染操作就行了,而不用去关心内部的计算。

主要代码如下

const io = new IntersectionObserver(()=>{ // 实例化 默认基于当前视窗
	
}) 

let ings = document.querySelectorAll('[data-src]') // 将图片的真实url设置为data-src src属性为占位图 元素可见时候替换src

function callback(entries){ 
	entries.forEach((item) => { // 遍历entries数组
		if(item.isIntersecting){ // 当前元素可见
			item.target.src = item.target.dataset.src // 替换src
			io.unobserve(item.target) // 停止观察当前元素 避免不可见时候再次调用callback函数
		}	
	})
}

imgs.forEach((item)=>{ // io.observe接受一个DOM元素,添加多个监听 使用forEach
	io.observe(item)
})

本想录制个GIF图,使用Recordlt始终上传不了,谁有好用的GIF图录制软件请推荐个,不胜感激。。

呐,给你花:rose:

因篇幅有限,完整代码请戳 github

注意

目前IntersectionObserver是一个实验中的功能,请酌情使用。

谈谈IntersectionObserver懒加载的具体使用

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

Javascript 相关文章推荐
FormValid0.5版本发布,带ajax自定义验证例子
Aug 17 Javascript
Javascript常用字符串判断函数代码分享
Dec 08 Javascript
用js编写的简单的计算器代码程序
Aug 04 Javascript
不得不分享的JavaScript常用方法函数集(上)
Dec 23 Javascript
ajax在兼容模式下失效的快速解决方法
Mar 22 Javascript
BootStrap给table表格的每一行添加一个按钮事件
Sep 07 Javascript
JavaScript实现三级级联特效
Nov 05 Javascript
jQuery实现验证表单密码一致性及正则表达式验证邮箱、手机号的方法
Dec 05 jQuery
在Vue中使用Compass的方法
Mar 02 Javascript
Vue+ElementUI table实现表格分页
Dec 14 Javascript
如何利用JS将手机号中间四位变成*号
Sep 29 Javascript
解读Vue组件注册方式
May 15 Vue.js
js实现开关灯效果
Mar 30 #Javascript
JS实现灯泡开关特效
Mar 30 #Javascript
浅谈微信小程序列表埋点曝光指南
Oct 15 #Javascript
javascript网页随机点名实现过程解析
Oct 15 #Javascript
javascript随机变色实例代码
Oct 15 #Javascript
vue中axios的二次封装实例讲解
Oct 14 #Javascript
Vue项目打包部署到iis服务器的配置方法
Oct 14 #Javascript
You might like
深思 PHP 数组遍历的差异(array_diff 的实现)
2008/03/23 PHP
php递归使用示例(php递归函数)
2014/02/14 PHP
php array_merge函数使用需要注意的一个问题
2015/03/30 PHP
PHP生成json和xml类型接口数据格式
2015/05/17 PHP
PHP实现文件上传与下载实例与总结
2016/03/13 PHP
Laravel框架实现发送短信验证功能代码
2016/06/06 PHP
PHP中类的自动加载的方法
2017/03/17 PHP
php实现的中秋博饼游戏之绘制骰子图案功能示例
2017/11/06 PHP
Json字符串转换为JS对象的高效方法实例
2013/05/01 Javascript
转义字符(\)对JavaScript中JSON.parse的影响概述
2013/07/17 Javascript
jquery事件与函数的使用介绍
2013/09/29 Javascript
jQuery表格行上移下移和置顶的实现方法
2015/10/08 Javascript
Node.js中Request模块处理HTTP协议请求的基本使用教程
2016/03/31 Javascript
Bootstrap中文本框的宽度变窄并且加入一副验证码图片的实现方法
2016/06/23 Javascript
Angularjs中$http以post请求通过消息体传递参数的实现方法
2016/08/05 Javascript
Js 获取、判断浏览器版本信息的简单方法
2016/08/08 Javascript
node.js缺少mysql模块运行报错的解决方法
2016/11/13 Javascript
详解JS中定时器setInterval和setTImeout的this指向问题
2017/01/06 Javascript
input获取焦点时底部菜单被顶上来问题的解决办法
2017/01/24 Javascript
jquery获取下拉框中的循环值
2017/02/08 Javascript
微信小程序实现tab页面切换功能
2018/07/13 Javascript
layDate插件设置开始和结束时间
2018/11/15 Javascript
详解JavaScript数据类型和判断方法
2020/09/04 Javascript
跟老齐学Python之永远强大的函数
2014/09/14 Python
举例详解Python中threading模块的几个常用方法
2015/06/18 Python
Python tkinter模版代码实例
2020/02/05 Python
python中的 zip函数详解及用法举例
2020/02/16 Python
python解释器安装教程的方法步骤
2020/07/02 Python
python可视化 matplotlib画图使用colorbar工具自定义颜色
2020/12/07 Python
Herve Leger官网:标志性绷带连衣裙等
2018/12/26 全球购物
人民教师的自我评价分享
2014/02/21 职场文书
应急管理培训方案
2014/06/12 职场文书
2014年教师党员自我评价范文
2014/09/22 职场文书
幼儿园大班开学寄语(2015秋季)
2015/05/27 职场文书
Go语言基础切片的创建及初始化示例详解
2021/11/17 Golang
纯CSS打字动画的实现示例
2022/08/05 HTML / CSS