文档章节

你可能不知道的前端知识点之:IntersectionObserver

justjavac
 justjavac
发布于 2017/07/13 20:03
字数 809
阅读 4.1K
收藏 40

阿里云携手百名商业领袖、技术大咖,带您一探行进中的数字新基建!>>>

本文是我的 你可能不知道的前端知识点 系列的第 5 个知识点。

简介

  • 你想跟踪 DOM 树里的一个元素,当它进入可视区域时得到通知。
  • 你想实现延迟加载图片功能
  • 你需要知道用户是否真的在看一个广告 banner。

你可以通过绑定 scroll 事件或者用一个周期性的定时器,然后在回调函数中调用元素的 getBoundingClientRect() 获取元素位置实现这个功能。但是,这种实现方式性能极差,因为每次调用 getBoundingClientRect() 都会强制浏览器 重新计算整个页面的布局 ,可能给你的网站造成相当大的闪烁。

IntersectionObserver 就是为此而生的,它可以检测一个元素是否可见,IntersectionObserver 能让你知道一个被观测的元素什么时候进入或离开浏览器的视口。

兼容性

  • Chrome 51+(发布于 2016-05-25)
  • Android 5+ (Chrome 56 发布于 2017-02-06)
  • Edge 15 (2017-04-11)
  • iOS 不支持

Polyfill

WICG 提供了一个 polyfill

 IntersectionObserver polyfill justjavac

实用程度

★★★★

相关链接

FAQ

:摘录自 IntersectionObserver’s Coming into View

IntersectionObservers deliver their data asynchronously, and your callback code will run in the main thread. Additionally, the spec actually says that IntersectionObserver implementations should use requestIdleCallback(). This means that the call to your provided callback is low priority and will be made by the browser during idle time. This is a conscious design decision.

从规范来看,IntersectionObserver的实现应该使用requestIdleCallback,那就是说IntersectionObserver的优先级比较低,低优先级在什么情况下会造成什么问题吗?

IntersectionObservers 的回调是异步执行的,但是也提供了同步调用的方法 IntersectionObserver.takeRecords()

每一个 IntersectionObserverEntry 都是 [[QueuedEntries]]。当观察到交互动作发生时,回调函数并不会立即执行,而是在空闲时期使用 requestIdleCallback 来异步执行回调函数,而且还规定了最大的延迟时间是 100 毫秒(???),相当于我么你的代码 1-100 毫秒内执行。

我们可以看一下 polyfill 的实现:

To enable polling for all instance, set a value for POLL_INTERVAL on the IntersectionObserver prototype:

IntersectionObserver.prototype.POLL_INTERVAL = 100; // Time in milliseconds.

Enabling polling for individual instance:

To enable polling on only specific instances, set a POLL_INTERVAL value on the instance itself:

var io = new IntersectionObserver(callback);
io.POLL_INTERVAL = 100; // Time in milliseconds.
io.observe(someTargetElement);

Note: the POLL_INTERVAL property must be set prior to calling the .observe method, or the default configuration will be used.

如果执行的是紧急任务,不想异步执行,可以调用同步方法 takeRecords()

Intersection Observers Explainer Doc 中有个显示广告的例子:

function visibleTimerCallback(element, observer) {
  delete element.visibleTimeout;
  // Process any pending observations
  processChanges(observer.takeRecords());
  if ('isVisible' in element) {
    delete element.isVisible;
    logImpressionToServer();
    observer.unobserve(element);
  }
}

如果异步的回调先执行了,那么当我们调用同步的 takeRecords() 方法时会返回空数组。同理,如果已经通过 takeRecords() 获取了所有的观察者实例,那么回调函数就不会被执行了。在规范中或者 polyfill 代码已经很清楚了。

综上:

  1. IntersectionObserver 虽然优先级低,但是可以保证肯定会执行
  2. 如果需要立即执行,可以使用同步的 takeRecords() 方法

更多关于 IntersectionObserver 的讨论可以在 issues #10

© 著作权归作者所有

justjavac

justjavac

粉丝 326
博文 149
码字总数 189426
作品 3
南开
私信 提问
加载中

评论(0)

使用Intersection Observer API实现视频队列自动播放

前言 笔者利用空余时间研究了一下javascript的Intersection Observer API,发现其有很大的应用场景,比如图片或者内容的懒加载,视差动画等。笔者也在之前的文章中详细介绍了3种Observer(观...

徐小夕
05/25
0
0
【前端词典】4 个实用有趣的 JS 特性

前言 最近在学习的过程中发现了我之前未曾了解过的一些特性,发现有些很有趣并且在处理一些问题的时候可以给我一个新的思路。 这里我将这些特性介绍给大家。 4 个有趣的 JS 特性 利用 a 标签...

小生方勤
2019/07/01
0
0
页面需要渲染10万条数据,应该怎么实现?

关键点:不卡顿,交互流畅 一、最传统、最简单粗暴的方式 chrome浏览器(版本 74.0.3729.169(正式版本) (64 位))控制台运行结果如下 也就是说,渲染包含十万条记录,每一条数据仅仅只有...

ldld
2019/06/15
0
0
IntersectionObserver是什么?

IntersectionObserver.png IntersectionObserver概览 IntersectionObserver构造器 IntersectionObserver方法 IntersectionObserver懒加载(vue单文件组件版) IntersectionObserver吸顶(vue......

趁你还年轻233
2019/11/20
0
0
几个非常有意思的javascript知识点总结

作为一名前端爱好者, 笔者利用空余时间研究了几个国外网站的源码,发现不管是库,还是业务代码,都会用到了一些比较有意思的API,虽然平时在工作中部分接触过,但是经过这次的研究,觉得很有必要总...

徐小夕
04/17
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Mysql经典SQL注入(注释法:# 或 --)

所谓SQL注入,就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。 我们永远不要信任用户的输入,我们必须认定用户输入的数据都是...

二营长意大利炮
31分钟前
11
0
辨别高防服务器的4种方法你知道吗

  由于高防服务器的品牌以及型号种类很多,所以高防服务器的性能也有着很大的差别,所以辨别高防服务器的方法就显得尤为的重要,那么主机侦探今天就来讲讲辨别高防服务器的4种最有效的方法...

silence主机
33分钟前
23
0
录音软件有哪些推荐?

最近,很多人都在询问:录音软件哪一款比较好用?最开始,我使用的是手机自带的录音软件,但因其功能单一便渐渐摒弃不用了。后来,有了解到一款多功能的录音软件“录音转文字助手”APP,很多...

茹鋽
38分钟前
16
0
spring boot到底干了啥(二)

目录 spring boot到底干了啥(一) run() public ConfigurableApplicationContext run(String... args) {........//<4> ConfigurableEnvironment environment = this.prepareE......

街角的小丑
39分钟前
10
0
彻底解决delphi WebBroker服务器中文乱码 delphi WebBroker服务器不能显示中文网页 WebBroker中文显示乱码

彻底解决delphi WebBroker服务器中文乱码 彻底解决WebBroker中文显示乱码 彻底解决delphi WebBroker服务器不能显示中文网页 这个问题被折腾惨啦! 网上一大堆,就没能彻底解决掉: https://...

simpower
43分钟前
18
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部