助你更容易理解IntersectionObserver.relativeToViewport的margins值
官方文档解释:指定页面显示区域作为参照区域之一,使用margins来扩展(或收缩)参照节点布局区域的边界。 [图片] 你如果已经通过官方文档完全理解了它,就可以直接跳过了,如果你还不能很理解,请往下看。 关于relativeToViewport(margins)的参数解释:一图胜千言,绿色为你的视口区域,红色部分就是相交事件的真实触发区域。 简单解释下,就是margins的4个方向上的正值向外放大的区域,margin的负值向内缩小的区域。 [图片] 1. top / bottom 负值:相对于视口的margin设置如下所示。top,bottom都为负值的处理。 this._observer
.relativeToViewport({top: -200, bottom: -200})
.observe('.ball', (res) => {
console.log(res);
})
当我们滚动页面,小球已经出现在视口内,但是我们log并没有打印出任何相交事件信息。 [图片] 因为,我们设置了bottom:-200,所以,真实的相交区域应该是如下图所示的区域: [图片] 2.top / bottom 正值: 相对于视口的margins设置如下所示。top,bottom都为正值的处理。 relativeToViewport({top: 10, bottom: 10})
[图片] left和right的正值、负值原理相同。 总结: top 正值往上,负值往下 bottom: 正值往下,负值往上 left 正值往左 负值往右 right 正值往右 负值往左 正值向外扩展,负值向内收缩。扩展缩放后的区域就是相对元素的参照触发区域。 另外有个问题,如果我们视口内有fixed定位元素,这些定位元素可能会影响用户对视口的理解偏差。 举例说明,下图中的红色部分都为fixed元素,在视口外有个小球,当参照区域与小球相交比例为1时需要做一些逻辑处理。如果我们不做特殊的margins值设置,那么当小球完全进入视口但未完全进入蓝色区域时就会被触发。这显然不是我们想要的,当然我们完全可以通过设置margins为四个方向的负值来完成这件事情。但是在现实开发中,组件多为独立的自定义组件,是否存在和宽高都是未知,我们需要更完整的整套解决方案更为合适。 后续的文章我们会针对这个问题,提供一整套基于官方relativeToViewport封装的解决方案。以做到包装后的relativeToViewport针对的就是图中的用户理想视口(蓝色区域),设置的margins值就是对图中蓝色区域的缩放。 [图片]