-
-
Notifications
You must be signed in to change notification settings - Fork 117
Open
Labels
Description
简介
- 你想跟踪 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
✔ |
✔ |
6+ |
✔ |
7+ |
✔ |
4.4+ |
实用程度
★★★★
相关链接
- IntersectionObserver’s Coming into View
- API Sketch for Intersection Observers
- IntersectionObserver API 使用教程
- 使用 IntersectionObserver 和 registerElement 打造 Lazyload 使用 IntersectionObserver 和 registerElement 打造 Lazyload brunoyang/blog#19
runjuu, Hugo-seth, FrankFang, thedb, xwillmadeit and 2 morerunjuu and haoliangwu
Metadata
Metadata
Assignees
Labels
Projects
Milestone
Relationships
Development
Select code repository
Activity
liudianliang commentedon Jul 7, 2017
不支持IOS是不是意味着不能做移动端了?
justjavac commentedon Jul 8, 2017
有 polyfill
jiangtao commentedon Jul 10, 2017
写了个demo, 比如 我要在滚动到离图片的位置多出300距离做操作, 就得在图片相邻的地方插入一个元素,或者在优化下用一个元素,但是增加了计算量 ,absolute且物理位置隐藏, 然后才能原有的效果。
相比较于,requestIdleCallback 做调度也能做不少事情。
不过这个api在一些需求上 确实很好使。
Tao-Quixote commentedon Jul 10, 2017
摘录自IntersectionObserver’s Coming into View
从规范来看,
IntersectionObserver
的实现应该使用requestIdleCallback
,那就是说IntersectionObserver
的优先级比较低,低优先级在什么情况下会造成什么问题吗?justjavac commentedon Jul 10, 2017
IntersectionObservers
的回调是异步执行的,但是也提供了同步调用的方法IntersectionObserver.takeRecords()
。每一个
IntersectionObserverEntry
都是 [[QueuedEntries]]。当观察到交互动作发生时,回调函数并不会立即执行,而是在空闲时期使用requestIdleCallback
来异步执行回调函数,而且还规定了最大的延迟时间是 100 毫秒(???),相当于我么你的代码 1-100 毫秒内执行。我们可以看一下 polyfill 的实现:
如果执行的是紧急任务,不想异步执行,可以调用同步方法
takeRecords()
在 Intersection Observers Explainer Doc 中有个显示广告的例子:
如果异步的回调先执行了,那么当我们调用同步的
takeRecords()
方法时会返回空数组。同理,如果已经通过takeRecords()
获取了所有的观察者实例,那么回调函数就不会被执行了。在规范中或者 polyfill 代码已经很清楚了。综上:
IntersectionObserver
虽然优先级低,但是可以保证肯定会执行takeRecords()
方法justjavac commentedon Jul 12, 2017
今天在 github trending 看到一个项目:stratiformltd/react-loadable-visibility
react-loadable-visibility 包装了 react-loadable 和 loadable-components,并且使用了
IntersectionObserver 当指定元素进入到 viewport 时加载组件。
参考
leixus commentedon Jun 25, 2018
很好的 +111