资讯专栏INFORMATION COLUMN

Javascript零碎之IntersectionObserver

张迁 / 1557人阅读

摘要:主要用于元素可见性的监听,比传统通过全局监听事件去判断可见性无论是性能还是便利性都要好得多。问题是这种通过监听的方式很容易导致性能问题,或者多多少少会有些性能损失。

IntersectionObserver主要用于元素可见性的监听,比传统通过全局监听scroll事件去判断可见性无论是性能还是便利性都要好得多。因为api比较新,存在兼容性问题,好在已经有了兼容的polyfill.其基本介绍和使用方式都可以在该polyfill对应网站上看到。这里主要通过例子的形式,说明其实用的场景。

图片懒加载 之前的方式

以前我们实现图片懒加载的原理是这样的:

window.addEventListener("scroll", lazyload);
function lazyload() {
    const imgs = document.querySelector(".img");
    const innerHeight = util.innerHeight();
    const scrollTop = util.scrollTop();

    imgs.forEach((img) => {
        const imgOffsetH = util.getPosition(img).top;

        // 距离页面顶部的距离 <= 视窗高 + 往上滚进去的距离
        if(imgOffsetH <= innerHeight + scrollTop) {
            img.src = img.getAttribute("data-src");
        }
    })
}

条件是:距离页面顶部的距离 <= 视窗高 + 往上滚进去的距离,即算做图片可见了才加载它。问题是这种通过监听scroll的方式很容易导致性能问题,或者多多少少会有些性能损失。

IntersectionObserver的方式
const io = new IntersectionObserver((entrys) => {
    entrys.forEach((img) => {
        if(!img.isIntersecting) return;
        img.src = img.getAttribute("data-src");
        io.unobserve(img);
    })
}, {
      //即滚动到距离底部50px时开始算交互区
       rootMargin:"0px 0px 50px 0px"
})
imgs.forEach((img) => {
    io.observe(img);
})

非常的清晰和简单,而且由于是原生的功能,不会引起性能损耗。这里的rootMargin参数非常好用,因为一般情况下的交互条件都需要添加一定的阈值,以实现更优雅和流畅的体验,而通过rootMargin能非常简单的实现这点。

完整示例请参考lazyload.html
滚动分页 以前的方式

通过判断滚动是否到底部,即 视窗高+往上滚进去的距离>= 页面高,来作为加载新的一页的条件:

window.addEventListener("scroll", () => {
    const innerHeight = util.innerHeight();
    const scrollTop = util.scrollTop(); 
    const scrollHeight = util.scrollHeight();
    // 滚动到距离底部50px
    if(innerHeight + scrollTop >= scrollHeight - 50) {
        loadMore();
    }
});
IntersectionObserver的方式

在最底部设置一个加载更多的标记器,监听它是否出现,作为加载新页的条件:

const io = new IntersectionObserver((entrys) => {
    entrys.forEach((entry) => {
        if(!entry.isIntersecting) return;
        loadMore();
    })
}, {
    rootMargin:"0px 0px 50px 0px"
})
//监听最底部的loadmore是否出现
const lMore = document.querySelector(".load-more");
io.observe(lMore);

在性能上仍然更胜一筹,而且不必每次都去判断视窗高、滚进去的距离等等,将以往很麻烦的事情变得简单而快捷。

完整示例请参考paging.html

通过上面的两个例子,基本能了解IntersectionObserver的功能实用场景,即监听元素的出现,实现懒加载(可以是图片、模版、甚至组件等等)、元素进出动画、分页等各种形式的功能。这对优化整个页面的性能还是非常有帮助的,所以在日常的项目中还是很值得尝试。

本文收录在个人的Github上https://github.com/kekobin/bl... ,觉得有帮助的,欢迎start哈。支持原创,未经本人同意,请勿转载!

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/105176.html

相关文章

  • Javascript零碎各种宽高属性及应用

    摘要:一挂在上的上最常用的只有其中,永远都是窗口的大小,跟随窗口变化而变化。这个是距该元素最近的不为的祖先元素,如果没有则指向元素。 在Javascript的开发过程中,我们总会看到类似如下的边界条件判断(懒加载): const scrollTop = document.documentElement.scrollTop || window.pageYOffset || document.b...

    DevYK 评论0 收藏0
  • 图片懒加载的前世今生

    摘要:配置项配置项中的参数有以下三个所监听对象的具体祖先元素,默认是计算交叉状态时,将附加到祖先元素上,从而有效的扩大或者缩小祖先元素判定区域设置一系列的阈值,当交叉状态达到阈值时,会触发回调函数。 一、前言   通常情况下,HTML 中的图片资源会自上而下依次加载,而部分图片只有在用户向下滚动页面的场景下才能被看见,否则这部分图片的流量就白白浪费了。   所以,对于那些含有大量图片资源的网...

    zhaot 评论0 收藏0
  • 组件复用那些事儿 - React 实现按需加载轮子

    摘要:同时,懒加载按需加载概念至关重要。时至今日,这些实现懒加载脚本的代码仍有学习意义。代码实战下面让我们动手实现一个按需加载轮子。同样,对于组件也可以使用无状态组件函数式组件实现这样无疑更加简洁。 组件化在当今前端开发领域中是一个非常重要的概念。著名的前端类库,比如 React、Vue 等对此概念都倍加推崇。确实,组件化复用性(reusability)和模块性(modularization...

    lidashuang 评论0 收藏0
  • 组件复用那些事儿 - React 实现按需加载轮子

    摘要:同时,懒加载按需加载概念至关重要。时至今日,这些实现懒加载脚本的代码仍有学习意义。代码实战下面让我们动手实现一个按需加载轮子。同样,对于组件也可以使用无状态组件函数式组件实现这样无疑更加简洁。 组件化在当今前端开发领域中是一个非常重要的概念。著名的前端类库,比如 React、Vue 等对此概念都倍加推崇。确实,组件化复用性(reusability)和模块性(modularization...

    K_B_Z 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<