最近项目中多次用到 IntersectionObserver 懒加载,在这里记录一下IntersectionObserver API 的使用
工作用到的场景:
1、Shoplnk 获取展示Instagram和Facebook的图片时使用懒加载
2、Instabio biolink 的button 先加载7条按钮 当最后一条出现时再展示下7条,一次类推。
3、Linkfly 当页面展示到 当前这块内容时执行一次动画。

一、IntersectionObserver 介绍

IntersectionObserver接口 (从属于Intersection Observer API) 提供了一种异步观察目标元素与其祖先元素或顶级文档视窗(viewport)交叉状态的方法。祖先元素与视窗(viewport)被称为根(root)。

简单来说是监听目标元素与其祖先或视窗交叉状态的手段,其实就是观察一个元素是否在视窗可见。

IntersectionObserver API-MDN

二、IntersectionObserver 使用

创建一个相交观察器

let options = {
  root: document.querySelector('#scrollArea'),
  rootMargin: '0px',
  threshold: 1.0
}

let observer = new IntersectionObserver(callback, options);

交叉口观察员选项

options传递给IntersectionObserver()构造函数的对象使您可以控制调用观察者的回调的环境。它具有以下字段:

  1. root : 所监听对象的具体祖先元素(element)。如果为传入值或值为null,则默认使用顶级文档的视窗。
  2. rootmargin:用来扩大或缩小视窗的大小,使用css的定义方法, 默认值为"0px 0px 0px 0px"。
  3. thresholds:用来指定交叉比例,决定什么时候触发回调函数,是一个数组,默认是[0]。

定位要观察的元素

创建观察者后,需要给它一个目标元素以进行观察:

let target = document.querySelector('#listItem');
observer.observe(target);

每当目标达到为所指定的阈值时IntersectionObserver,就会调用回调。回调接收IntersectionObserverEntry对象和观察者的列表:

let callback = (entries, observer) => {
  entries.forEach(entry => {
    // Each entry describes an intersection change for one observed
    // target element:
    //   entry.boundingClientRect
    //   entry.intersectionRatio
    //   entry.intersectionRect
    //   entry.isIntersecting
    //   entry.rootBounds
    //   entry.target
    //   entry.time
  });
};

使用示例

<!DOCTYPE html>
<html>
<head>
	<title></title>
<style type="text/css">
	img{max-width:100%;max-height:100%;}
	.box{width:360px;height:380px;display: flex;flex-direction: column;overflow: auto;padding:40px;margin: 0 auto;}
	.box img{height: 100%;}
</style>
</head>
<body>
<div class="box">
	<img src="./img/109951164469949594.jpg">
	<img src="./img/109951164469949594.jpg">
	<img src="./img/109951164469949594.jpg">
	<img src="./img/109951164469949594.jpg">
	<img src="./img/109951164469949594.jpg">
</div>
<script type="text/javascript">
	var loadCnt = 0;
	function callback(entries){
		entries.forEach(entry => {
		    if (entry.intersectionRatio > 0 || entry.isIntersecting) {
				io.unobserve(entry.target)
				if(loadCnt < 10){
					loadCnt++;
					for (var i = 0; i < 5; i++) {
						var img = document.createElement('img');
						img.src = './img/109951164469949594.jpg';
						document.querySelector('.box').appendChild(img)
						if(i==3&&loadCnt!=9){
							io.observe(img);
						}
					}
				}
		    }
		 })
	}
	const options = {
	    root:null,
	    threshold:[1]
	}
	var io = new IntersectionObserver(callback, options);
	io.observe(document.querySelectorAll('img')[3]);
</script>
</body>
</html>
Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐