观察口 抓包
“交集观察器”提供了一种异步观察元素交集(重叠)变化的方法。 这可能与其他元素或视口有关。 在本文中,我们将看一些演示,并讨论Intersection Observer在未来对Web开发人员的影响。 我还将分享代码示例,以帮助您开始那些深夜的实验会议。 让我们潜入吧!
交叉口观察员可以做什么?
使用IntersectionObserver
API,您可以注册一个回调函数,该函数将在受监视的元素进入或退出另一个元素或视口时执行 。
在GitHub上的W3C 解释器文档中有很多想法和建议,但是,Intersection Observer可以方便地本地构建功能,例如:
- 延迟加载
- 无限滚动
- 报告可见性/位置
- 执行动画
请查看Dan Callahan的演示,以阐明我们在说什么:
要开始使用IntersectionObserver
让我们探索所需的适当编码步骤。 您始终可以通过引用caniuse来确保所需的浏览器/设备支持IO API。 我们将从创建观察者开始,并讨论如何将其用于监视组件。
创建一个观察者
IntersectionObserver
首先需要定义为对象文字的一组选项,并将它们作为参数传递给您定义的观察者对象。
let options = {
root: null, // relative to document viewport
rootMargin: '0px', // margin around root. Values are similar to css property. Unitless values not allowed
threshold: 1.0 // visible amount of item shown in relation to root
};
let observer = new IntersectionObserver(callback, options);
当检测目标元素相对于根的可见性时,第2-4行的这些观察者选项将规定一些重要的细节。 观察者对象的第一个参数(最后一行)表示一个回调(函数),当观察者满足要求时执行该回调。 第二个参数引用包含观察者选项的对象文字,并接受以下属性:
-
root
:您要测试交集的元素。 值为null
表示浏览器的视口。 您还可以传入DOM选择器方法,例如document.querySelector('#mytargetobject')
。 -
rootMargin
:如果需要在计算交集之前扩大或缩小根元素的有效大小。 传递的这些值类似于CSSmargin
属性。 如果指定了root
元素,则值可以是百分比。 -
threshold
:指示目标可见性的百分比触发观察者回调的单个数字或数字数组。 值1.0表示在每个像素可见之前都不会认为阈值已通过,而0表示该元素完全不在视野范围内。
如前所述,您将通过创建一个包含基于项目需求的自定义逻辑的函数来处理回调参数。 只要观察到的元素相对于定义的根元素可见,就会执行此逻辑。
function onChange(changes, observer) {
// logic goes here
}
let observer = new IntersectionObserver(onChange, options);
观察者功能内的逻辑可以是事件,例如加载图像,添加/删除类或控制可见性,但是您可以根据自己的需求和目标来选择从内部执行什么操作。
每次观察者检测到更改时,都会从观察者回调中报告changes
事件(类似于报告事件对象的function()
之类function()
。 通过使用此触发事件,我们可以在运行任何其他逻辑之前通过检测change
事件的属性来检查元素相对于根的可见性。 一些开发人员将changes
用entries
代替changes
,但两种方法的工作原理相同。
function onChange(changes, observer) {
changes.forEach(change => {
if (change.intersectionRatio > 0) {
// your observer logic
}
});
}
该循环表明“对于检测到的每个更改,请检查目标元素相对于定义的根当前是否可见(大于0)。” 使用0.0(不可见)到1.0(完全可见)之间的值, 相交比有助于报告多少元素可见。 您可以像观察者的选项中定义的threshold
属性一样来考虑交集比率。
观察法
到目前为止,我们已经创建了一个options对象,一个回调函数并定义了一个observer对象,但是我们仍然没有什么可观察的。 这是观察方法将投入使用的地方。
let images = document.querySelectorAll('img');
images.forEach(img => observer.observe(img));
此方法将元素添加到IntersectionObserver
监视的目标元素IntersectionObserver
。 在此示例中,我将通过从images
选择器参考获得的结果来观察页面上的每个图像。 observe()
方法将继续监视目标,直到发生以下任何一种情况:调用unobserve()
或disconnect()
方法以及删除目标元素或相交根。 如果您不再需要观察元素,则最好调用unobserve()
并将目标作为参数传递。
支持条件
如果需要功能测试此API的支持,则可以将所有内容包装在if
/ else
条件语句中,如下所示:
if ('IntersectionObserver' in window) {
// supported
} else {
// not supported
}
由于Intersection Observer API仍位于工作草案阶段,因此我建议您进行检测window
对象的功能,或者如果愿意,也可以找到polyfills 。
现场例子
以下演示包含我到目前为止讨论的所有代码,并进行了一些其他调整。 当演示相对于视口显示其可见性的50%时,此演示懒惰加载图像。
与Chrome和Firefox中的img
元素相比, picture
元素的行为可能有所不同。 两种浏览器都能完美加载picture
元素,但是即使定义了绝对大小约束, picture
无视我们的阈值。 当它们的视角约为10%(演示中定义的阈值为50%)时,它们似乎已加载。 如果您注意到这种怪异,或者在IntersectionObserver
和picture
方面遇到了问题,请在下面发表评论。
这是另一个创建无限滚动场景的演示,该场景使用Ajax懒惰加载图像以根据需要加载图像。
在这种情况下,我将一个前哨插入DOM作为观察到的目标。 该标记将放置在无限滚动器中的最后一项旁边,并且随着标记的出现,回调将加载数据,创建下一项,将它们附加到DOM并重新放置标记。 如果您正确地回收了哨兵,则不需要额外调用observe()
。 这是 Google开发人员小组提供的一张很棒的图表 ,有助于直观地说明这种方法。
关于图像的注释
当观察到max-width: 100%
限制为max-width: 100%
的img
元素时,它将无法加载。 这意味着任何以惰性方式加载的图像都必须在CSS中定义约束或相应地内联。缺少任何约束的picture
元素的问题在于,在其内容加载之前大小为零; 表示在滚动时它们都同时与视口相交。 我怀疑getBoundingClientRect()
是原因的一部分,因为这是获取元素坐标和约束的主要方法之一。
结论
您现在是否正在自己的工作中使用IntersectionObserver
? 您为该功能及其带来的可能性感到兴奋吗? IntersectionObserver
是否可以取代对基于事件的功能(例如position: sticky
? 我个人觉得这个新的API是对我们规范的坚实补充,我热切期望它在未来几年中会继续增长。
我在下面提供了一些有用的链接,并鼓励您在空闲时间做更深入的研究。 每个链接将帮助您更好地了解此新API的工作原理和功能。 如果您有其他提示或技巧,请留在下面的评论中。 一如既往,祝您编程愉快!
翻译自: https://webdesign.tutsplus.com/tutorials/how-to-intersection-observer--cms-30250
观察口 抓包