Intersection Observer

背景

网页的开发,经常需要了解某个元素是否进入了“视口”,即用户能不能看到它

技术实现方案:

  • 监听scroll事件
  • Intersection Observer API

第一种,传统的实现方案计算量很大,容易造成性能问题;第二种名为“交叉观察器”,可以自动“观察元素”是否可见。接下来,将深入看看此API

API

ConstructorIntersectionObserver()监听目标元素的可见部分穿过一个或多个阈时,会执行指定的回调函数
属性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:目标元素的可见比例,即intersectionRectboundingClientRect的比例,完全可见时为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

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值