懒加载处理
利用浏览器原生提供的构造函数 IntersectionObserver
, 不要再傻傻监听页面滚动
一、IntersectionObserver
简介
1. 语法
let observer = new IntersectionObserver(callback, option);
/*
callback 是当被监听元素的可见性变化时,触发的回调函数
option 是一个配置参数,可选,有默认的属性值
*/
2. callback 参数
目标元素的可见性变化时,就会调用观察器的回调函数callback。
callback一般会触发两次。一次是目标元素刚刚进入视口(开始可见),另一次是完全离开视口(开始不可见)。
let observer = new IntersectionObserver(
entries => {
/*
entries是一个数组,每个成员都是一个IntersectionObserverEntry对象
如果同时有两个被观察的对象的可见性发生变化,entries数组就会有两个成员
*/
console.log(entries);
});
3. IntersectionObserverEntry对象
IntersectionObserverEntry对象提供目标元素的信息,一共有六个数组和链表的区别属性
-
time
: 可见性发生变化的时间,是一个高精度时间戳,单位为毫秒; -
target
: 被观察的目标元素,是一个 DOM 节点对象; -
rootBounds
: 根元素的矩形区域的信息,getBoundingClientRect()方法的返回值,如果没有根元素(即直接相对于视口滚动),则返回n数组去重方法ull; -
boundingClientRect
: 目标元素的矩形区域的信息; -
intersectionRect
: 目标元素与视口(或根元素)的交叉区域的信息仓鼠饲养八大禁忌; -
in长沙师范学院tersectionRati容器o
: 目标元素的可见比例,即intersectionRect占boun线程的几种状态dingClientR浏览器ect的比例,完全可见时为1,完全不可见时小于等于0;
4. option 对象
4.1 threshold
属性
new IntersectionObserver(
entries => {
// do something
},
{
threshold: [0, 0.25, 0.5, 0.75, 1]
}
);
/*
threshold属性决定了什么时候触发回调函数。
它是一个数组,每个成员都是一个门槛值,默认为[0],即交叉比例(intersectionRatio)达到0时触发回调函数。
用户可以自定义这个数组。
比如,[0, 0.25, 0.5, 0.75, 1]就表示当目标元素 0%、25%、50%、75%、100% 可见时,会触发回调函数。
*/
4.2 root
属性,rootMargin
属性
new IntersectionObserver(
entries => {
// do something
},
{
root: document.querySelector('#box'),
rootMargin: '10px 20px 30px 40px'
}
);
/*
root属性指定目标元素所在的容器节点(即根元素)。注意,容器元素必须是目标元素的祖先节点。
rootMargin定义根元素的margin,
用来扩展或缩小rootBounds这个矩形的大小,从而影响intersectionRect交叉区域的大小。
它使用CSS的定义方法,比如10px 20px 30px 40px,表示 top、right、bottom 和 left 四个方向的值。
这样设置以后,不管是窗口滚动或者容器内滚动,只要目标元素可见性变化,都会触发观察器。
*/
5. 注意
IntersectionObserver API 是异步的,不随着目标元素的滚动同步触发。
规格写明,Int陈思思ersectionObserver的陈思思实现,应该采用requestIdleCallback(),即只有线程空闲下来,才会执行观察器。
这意味着,这个观察器的优先级非常低,只在其他任务执行完,浏览器有了空闲才会执行。
二、应用,以指令形式
<template>
<div v-lazy-component="init">
</div>
</template>
<script>
export default {
directive: {
'lazy-component': {
// 只调用一次
bind(el, binding) {
// 判断是否可以使用
if ('IntersectionObserver' in window) {
// IntersectionObserver对象,浏览器原生提供的构造函数
let observer = new IntersectionObserver((entries) => {
// intersectionRatio: 目标元素的可见比例,即intersectionRect占boundingClientRect的比例,完全可见时为1,完全不可见时小于等于0
// 是否交叉
const isIntersected = entries.some(entry => entry.intersectionRatio > 0);
if (isIntersected) {
// 执行绑定的事件
binding.value();
// 停止观察
observer.unobserve(el);
// 关闭观察器
observer.disconnect();
}
});
// 开始观察, el: DOM对象
observer.observe(el);
} else {
binding.value();
}
}
}
},
methods: {
init() {
// do something
}
}
}
</script>