什么是观察者?
在深入了解现代浏览器支持的观察者系列之前,让我们先了解一般的观察者是什么?
观察者是一个观察或注意到某事的程序。观察者有助于观察浏览器中发生的某些活动并做出相应的响应。
我们经常处理用 addEventListener 来添加事件监听用户的各种操作,比如:click, mousedown, drag, wheel 等(完整事件列表参考:https://developer.mozilla.org/zh-CN/docs/Web/Events) 。
现代浏览器提供了 5 种 Observer ,使用这些 Observer ,我们可以观察浏览器中发生的不同类型的活动,并采取必要的行动。例如。我们可以观察到,视频是否显示在视口中并启用自动播放,是否已从父 DOM 元素中添加或删除子元素,是否更改了框元素的大小 / 尺寸等等。
以下是现代浏览器支持的五种不同类型的 Observer 。
Intersection Observer
Mutation Observer
Performance Observer
Resize Observer
ReportingObserver
Intersection Observer(https://developer.mozilla.org/zh-CN/docs/Web/API/IntersectionObserver)
用于观察两个 html DOM 元素之间的交集。当元素进入或离开可见视口时,观察 DOM 中的元素很有用。Intersection Observer 的一些用例描述如下
- 当元素在视口中可见时延迟加载图像或其他资源。
- 识别广告的可见性并计算广告收入。
- 当用户向下滚动页面时实现 **“无限滚动”** 网站,这样他们就不必浏览不同的页面。
- 当元素在视口内时加载和自动播放视频或动画。
** 浏览器支持:** 目前,firefox 和 chrome 支持 Intersection 观察器,但我们可以为旧浏览器找到 polyfill
使用 IntersectionObserver api 主要需要三个步骤
a) 定义回调处理程序
b) 创建观察者
c) 定义要观察的目标对象
a) 定义回调处理程序
这是当人们注意到警报时做出的响应,因为通常发生了一些事情。每当目标元素与根元素通过阈值相交时,就会触发回调处理程序。
语法:
const observer = new IntersectionObserver(callback[, options]);
callback
当元素可见比例超过指定阈值后,会调用一个回调函数,此回调函数接受两个参数:
entries
一个 IntersectionObserverEntry 对象的数组,每个被触发的阈值,都或多或少与指定阈值有偏差。
observer
被调用的 IntersectionObserver 实例。
//entries 一个 IntersectionObserverEntry 对象的数组,每个被触发的阈值,都或多或少与指定阈值有偏差。 | |
// https://developer.mozilla.org/zh-CN/docs/Web/API/IntersectionObserverEntry | |
function handler(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 | |
}); | |
} |
参考:https://developer.mozilla.org/zh-CN/docs/Web/API/IntersectionObserver/IntersectionObserver
b)** 创建观察者
** 只需调用构造函数 IntersectionObserver 并传递处理函数和配置选项即可创建。
语法:
const observer = new IntersectionObserver(callback[, options]);
options 可选
一个可以用来配置 observer 实例的对象。如果 options 未指定,observer 实例默认使用文档视口作为 root,并且没有 margin,阈值为 0%(意味着即使一像素的改变都会触发回调函数)。你可以指定以下配置:
root
监听元素的祖先元素 Element 对象,其边界盒将被视作视口。目标在根的可见区域的的任何不可见部分都会被视为不可见。
rootMargin
一个在计算交叉值时添加至根的边界盒 (bounding_box(en-US)) 中的一组偏移量,类型为字符串 (string) ,可以有效的缩小或扩大根的判定范围从而满足计算需要。语法大致和 CSS 中的 margin 属性等同;可以参考 The root element and root margin in Intersection Observer API 来深入了解 margin 的工作原理及其语法。默认值是 "0px 0px 0px 0px"。
threshold
规定了一个监听目标与边界盒交叉区域的比例值,可以是一个具体的数值或是一组 0.0 到 1.0 之间的数组。若指定值为 0.0,则意味着监听元素即使与根有 1 像素交叉,此元素也会被视为可见。若指定值为 1.0,则意味着整个元素都在可见范围内时才算可见。可以参考 Thresholds in Intersection Observer API 来深入了解阈值是如何使用的。阈值的默认值为 0.0。
const options = { | |
root: document.querySelector(".scrollContainer"), | |
rootMargin: ‘0px’, | |
threshold: [0.3, 0.5, 0.8, 1] | |
}; | |
const observer = new IntersectionObserver(handler, options); |
参考:https://developer.mozilla.org/zh-CN/docs/Web/API/IntersectionObserver/IntersectionObserver
[0.3] 的阈值意味着,当目标元素在根元素指定的元素内有 30% 可见时,调用处理函数。这意味着只要元素可见 30%、50%、80% 和 100%,就会调用处理程序 / 回调函数。
c) 定义要观察的目标对象
我们可以定义多个要观察的目标对象。如前例所述,狗在提醒所有人之前应该知道要观察什么。** 只需调用相应观察者的.observe (target)** 方法
即可观察任何目标元素。
const target = document.querySelector(“.targetBox”); | |
observer.observe(target); |
参考:https://developer.mozilla.org/zh-CN/docs/Web/API/IntersectionObserver/observe