Intersection Observer
Posted 杨晓风-linda
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Intersection Observer相关的知识,希望对你有一定的参考价值。
背景
网页的开发,经常需要了解某个元素是否进入了“视口”,即用户能不能看到它
技术实现方案:
- 监听scroll事件
- Intersection Observer API
第一种,传统的实现方案计算量很大,容易造成性能问题;第二种名为“交叉观察器”,可以自动“观察元素”是否可见。接下来,将深入看看此API
API
Constructor | IntersectionObserver() | 监听目标元素的可见部分穿过一个或多个阈时,会执行指定的回调函数 |
属性 | root | 监听对象的具体祖先元素(element) 未传入值或值为null,默认使用顶级文档的视窗 |
rootMargin | 根边界盒的矩形偏移量 默认值:“0px 0px 0px 0px” 偏移量单位:像素 || 百分比 | |
thresholds | 监听对象的交叉区域与边界区域的比率 如果构造器为传入值,默认值为0 | |
方法 | disconnect() | 停止监听工作 |
observe() | 开始监听一个目标元素 | |
takeRecords | 返回四偶有观察目标的对象数组 | |
unobserve() | 停止监听特定目标元素 |
用法
var io = new IntersectionObserver(callback, option);
- IntersectionObserver : 浏览器原生提供的构造函数,接收两个参数
- callback:可见性变化时的回调函数
- option: 配置对象
callback参数
var io = new IntersectionObserver (
entries =>
console.log(entries)
)
callback一般会触发两次:
- 目标元素刚刚进入视口
- 完全离开视口
IntersectionObserverEntry 对象
time: 0.92,
rootBounds: ClientRect
bottom: 100,
height: 800,
left: 10,
right: 600,
top: 0,
width: 300
,
boundingClientRect: ClientRect,
intersectionRect: ClientRect,
intersectionRatio: 0.54,
target: element
time
:可见性发生变化的时间,是一个高精度时间戳,单位为毫秒target
:被观察的目标元素,是一个 DOM 节点对象rootBounds
:根元素的矩形区域的信息,getBoundingClientRect()
方法的返回值,如果没有根元素(即直接相对于视口滚动),则返回null
boundingClientRect
:目标元素的矩形区域的信息intersectionRect
:目标元素与视口(或根元素)的交叉区域的信息intersectionRatio
:目标元素的可见比例,即intersectionRect
占boundingClientRect
的比例,完全可见时为1
,完全不可见时小于等于0
Option对象
var io = new IntersectionObserver (
entries =>
console.log(entries)
,
option
)
threshold属性
是一个数组,默认为[0],决定了监听对象的交叉区域与边界区域的比率为多少时触发回调函数
var io = new IntersectionObserver (
entries =>
console.log(entries)
,
threshold: [0, 0.25, 0.5, 0.75, 1]
)
root属性,rootMargin属性
root属性指定目标元素所在的容器节点(即根元素)(容器元素必须是目标元素的祖先节点)
rootMargin属性定义根元素的margin,用来扩展rootBounds矩形的大小,影响intersectionRect交叉区域的大小
应用实例
H5落地页feed流有埋点数据上报,进而进一步分析:
- 用户在商城的访购率or成交金额
- 常买落地页内的加购占商城加购比例
然而目前埋点曝光时机不对,没有出现在用户视窗内的商品卡也上报了。未解决此问题采用【Intersection Observer】
具体实现
mounted()
const that = this
// 根节点
const rootOpt = document?.getElementById(this.scrollElIdName) || document.getElementById('app')
// 配置对象
const options = root: rootOpt, rootMargin: '0px 0px -50px 0px', threshold: [1]
var intersectionObserver = new IntersectionObserver(function(entries)
// If intersectionRatio is 0, the target is out of view
// and we do not need to do anything.
// 如果不可见,就返回
if (entries[0].intersectionRatio <= 0) return;
// 停止监听工作
intersectionObserver.disconnect()//确保只上报一次,滑动再次出现在用户视窗内,不上报
that.reportGoodSW() // 执行的埋点上报方法
, options);
// start observing
intersectionObserver.observe(this.$refs.feedCard); // 观察的dom节点对象
fix
IntersectionObserver API 是异步的,不随着目标元素的滚动同步触发
IntersectionObserver
的实现,采用requestIdleCallback() 即
观察器的优先级非常低,只有其他任务执行完,浏览器有了空闲才会执行
参考链接:
IntersectionObserver API 使用教程 - 阮一峰的网络日志
Intersection Observer - Web API 接口参考 | MDN
以上是关于Intersection Observer的主要内容,如果未能解决你的问题,请参考以下文章
javascript Intersection Observer API示例