IntersectionObserver:ES6新的监听器API,能够监听一个或者多个盒子和浏览器可视窗口的交叉信息,只要盒子和可视窗口的交叉信息发生变化,则监听器就会被触发,我们可以做一些自己想做的事情
一、API
IntersectionObserver是浏览器原生提供的构造函数,接受两个参数:callback是可见性变化时的回调函数,option是配置对象(该参数可选)。
构造函数的返回值是一个观察器实例。实例的observe方法可以指定观察哪个 DOM 节点
//let ob = new IntersectionObserver(callback, option);let ob = new IntersectionObserver(callback,{//控制一露头算交叉状态改变0 默认为0 还是完全出现才算交叉状态改变1threshold:[1]//thresholds属性值为[0, 0.25, 0.5, 0.75, 1]})
// 监听DOM元素ob.observe(document.querySelector('#box'));// 移除监听ob.unobserve(element);
上面代码中,observe的参数是一个 DOM 节点对象。如果要观察多个节点,就要多次调用这个方法。
ob.observe(elementA);ob.observe(elementB);
二、callback 参数
目标元素的可见性变化时,就会调用观察器的回调函数callback。<br />
let ob = new IntersectionObserver(changes => {// 触发:// + 监听DOM元素后触发一次// + 刚一进入视口 触发一次// + 完全离开视口 触发一次console.log(changes);});
上面代码中,回调函数采用的是箭头函数的写法。callback函数的参数(changes)是一个数组,每个成员都是一个IntersectionObserverEntry对象。举例来说,如果同时有两个被观察的对象的可见性发生变化,changes数组就会有两个成员。
参数是个数组,即 changes=[…] ,数组中的每一项都是监听的元素的交叉信息,但可以循环绑定多次元素
示例:瀑布流案例中,一次只能监听一种元素(img),但img有多个,所以数组中每一项就是对应的交叉信息
let ob=new IntersectionObserver(changes=>{// 循环每个盒子监听到的交叉盒子,把出现在视口中的盒子做延迟加载changes.forEach(change=>{let{isIntersecting,target}=change;// target监听的盒子//isIntersecting 为 true 则是显示在了视口中// console.log(change);if(isIntersecting){// 当前盒子已经出现在视口中 target监听的盒子singleImgLazy(target.querySelector('img'));// 处理后 ,这个盒子就没必要再监听了ob.unobserve(target);}});},{// 控制完全出现在视口中 才算交叉状态改变threshold:[1]});
三、IntersectionObserverEntry 对象
IntersectionObserverEntry对象提供目标元素的信息每个属性的含义如下。
- target:监听的这个DOM元素对象
- boundingClientRect:元素和可视窗口的交叉信息
- isIntersecting:false 记录当前元素是否出现在可视窗口中(默认一露头就算)
<!DOCTYPE html><html><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>IntersectionObserver</title><link rel="stylesheet" href="css/reset.min.css"><style>html,body {height: 200%;background: -webkit-linear-gradient(top left, pink, orange);}#box {position: absolute;left: 200px;top: 800px;width: 100px;height: 100px;background: red;}</style></head><body><div id="box"></div><script>let box = document.querySelector('#box');/* let ob = new IntersectionObserver(changes => {// 当监听的元素和可视窗口交叉信息发生改变的时候触发执行// + changes记录每一个被监听的元素和可视窗口的交叉信息(数组)// 每一项记录的信息// boundingClientRect:{...} 元素和可视窗口的交叉信息// isIntersecting:false 记录当前元素是否出现在可视窗口中(默认一露头就算)// target:... 监听的这个DOM元素对象// 触发:// + 监听DOM元素后触发一次// + 刚一进入视口 触发一次// + 完全离开视口 触发一次console.log(changes);});// 监听DOM元素 unobserve就是移除监听ob.observe(box); */let ob = new IntersectionObserver(changes => {// 交叉状态改变,就会被触发执行console.log(changes);}, {// 控制一露头算交叉状态改变0 还是完全出现才算交叉状态改变1threshold: [1]});ob.observe(box);</script></body></html>
