浏览器提供api,用于检测目标元素和祖先元素/顶级文档视窗 (viewport) 交叉状态的方法。
const observer = new IntersectionObserver(function (IntersectionObserverEntry) {},options);
observer.observe(el);
构造函数接收一个回调函数,一个配置对象(可选),返回一个观察器实例。实例的observe方法接收一个dom节点作为观察的对象
当目标对象出现在视口的时候,会调用回调函数,传递一个元素都为IntersectionObserverEntry
对象的数组。
IntersectionObserverEntry
对象有以下属性 (只列举了这篇用到的两个):
created:在绑定元素的 attribute 或事件监听器被应用之前调用;
beforeMount:当指令第一次绑定到元素并且在挂载父组件之前调用;
mounted:在绑定元素的父组件被挂载后调用;
beforeUpdate:在更新包含组件的 VNode 之前调用;
updated:在包含组件的 VNode 及其子组件的 VNode 更新后调用;
beforeUnmount:在卸载绑定元素的父组件之前调用;
unmounted:当指令与元素解除绑定且父组件已卸载时,只调用一次;
Image 对象代表嵌入的图像。
created
的时候指令绑定的dom元素还没有attribute,也没有DOM结构,所以不适合,mounted
整个DOM元素已经挂载到页面上了,图片在挂载上去的时候就开始加载,再做懒加载已经没有意义了,所以使用beforeMount
,有完整的DOM结构,但是没有挂载到页面上。export const lazyLoad = {
beforeMount(el: any, binding: any, vnode: any, prevVnode: any) {
const img = el.querySelector(`.${el.className} img`);
const src = img.getAttribute("src");
// 图片使用loading gif替换
img.setAttribute("src", "https://m.tea7.com/images/imgLoading.gif");
// 新建Image对象
const tempImg = new Image();
tempImg.onload = function () {
img.setAttribute("src", src);
};
const parent = img.parentNode;
const observer = new IntersectionObserver(function (changes) {
// 可视
changes.forEach((item) => {
if (item.intersectionRatio !== 0) {
tempImg.src = src;
}
});
});
observer.observe(el);
},
};