1

想象一个需求场景。首页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


阿古达木
574 声望17 粉丝

牛逼的工程师就是能用简单的代码和思路写出复杂的功能