想象一个需求场景。首页feed流,一篇文章是一个模块,文章滑出过程中需要将文章标题图钉定位。同事为了区别标题与内容,需要给标题增加阴影效果。与知乎首页类似。
DEMO
我们可以通过监听scroll事件来实现这个功能,滚动回调中getBoundingClientRect
检测元素位置判断阴影的展示状态。这样虽然可以实现,但是非常不优雅。当页面承载的内容多了回流和性能问题会很严重。
下面给出一种优雅的解决方法。
实现一个方法叫wathcSticky
接受两个参数,被观察元素与它的container(不一定是父级)。当该元素处在sitcky状态事会向外派发sticky-change
事件。
自定义一个事件叫sticky-change
,callback中返回当前监听的元素和一个布尔值,表示当前元素是否正处在sticky状态。
document.addEventListener("sticky-change", function (e)
{
const { detail } = e;
const { target, status } = detail;
target.classList.toggle("shadow", status);
});
watchSticky(dom, container);
wathcSticky实现原理:
使用了Intersection_Observer_API,提供了一种异步检测目标元素与祖先元素或viewport 相交情况变化的方法。
在目标元素的上面和目标元素父级的最底部插入两个高度为0的div,命名为topDiv和bottomDiv,使用Intersection_Observer_API监听这个两个元素与container的相交情况。
如果topDiv的top值小于containerDiv的top,并且他俩是不相交的,则证明当前元素正在sticky中。
bottomDiv的判断反之。
CODE
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。