文档章节

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

justjavac
 justjavac
发布于 2017/07/13 20:03
字数 809
阅读 1230
收藏 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

粉丝 315
博文 149
码字总数 189426
作品 3
南开
你可能不知道的前端知识点

新建了一个 repo:justjavac/the-front-end-knowledge-you-may-dont-know 发掘被我们忽略的前端知识点。所有的讨论以 issues 的形式进行,任何人都可以在 issues 区围观讨论。 本 repo 的目的...

justjavac
2017/07/04
0
0
人在西邮 | 有一份前端需求等你签收

最近做了很多事情,忙得没时间写技术博客。 最值得回忆的,当然是 CreatShare 互联网实验室周年纳新活动。在十一号晚上的宣讲会上,我用生动的比喻,分享了《 漫话 JavaScript 奇异世界 》并...

韩亦乐
2017/10/22
0
0
从软件工程专业思考到的大前端技术栈-问答篇

时隔我的万字长文 《从软件工程专业思考到的大前端技术栈-详情篇》 在 GitChat 上发布一周后,于 2017 年 8 月 3 日晚上举行了与订阅者互动的线上交流环节。 惊喜的是,这场 Chat 最终有 21...

韩亦乐
2017/08/09
0
0
给在校准备找工作的同学的几个建议

欢迎访问个人站点 目录 了解 vim 养成 git 规范 学深比学广更重要 拥有自己的知识体系,形成解决问题的方法论 了解 vim Vim 被誉为"编辑器之神",这可不是虚的。 在我用了 vim 半年之后,我建...

萧然
05/22
0
0
迄今为止见过最牛逼的程序员,300行代码打造圣诞欢乐树!

  今天小编我逛论坛,今天小编在网上看到一个关于圣诞祝福的特效,使用JavaScript做的,不愧是前端领域的顶尖人物,抱着膜拜的心情,小编我也下载了一份源码进行学习运行,暂时没有发现一点...

万能的大白
2017/12/24
0
0

没有更多内容

加载失败,请刷新页面

加载更多

原型模式

1、原型模式-定义 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象 克隆(浅度克隆->拷贝值类型或者引用,深度克隆->创建新的对象,开辟新的内存) 例如客户端知道抽象Pro...

阿元
今天
57
0
awk命令扩展使用操作

awk 中使用外部shell变量 示例1 [root@centos01 t1022]# A=888[root@centos01 t1022]# echo "" | awk -v GET_A=$A '{print GET_A}'888[root@centos01 t1022]# echo "aaaaaaaaaaaaa" | aw......

野雪球
今天
48
0
深入解析MySQL视图VIEW

Q:什么是视图?视图是干什么用的? A:视图(view)是一种虚拟存在的表,是一个逻辑表,本身并不包含数据。作为一个select语句保存在数据字典中的。   通过视图,可以展现基表的部分数据;...

IT--小哥
今天
53
0
虚拟机学习之二:垃圾收集器和内存分配策略

1.对象是否可回收 1.1引用计数算法 引用计数算法:给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1;当引用失效时,计数器值就减1;任何时候计数器值为0的对象就是不可能...

贾峰uk
今天
56
0
smart-doc功能使用介绍

smart-doc从8月份底开始开源发布到目前为止已经迭代了几个版本。在这里非常感谢那些敢于用smart-doc去做尝试并积极提出建议的社区用户。因此决定在本博客中重要说明下smart-doc的功能,包括使...

上官胡闹
昨天
52
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部