实现图片懒加载以及图片懒加载的最佳解决方法IntersectionObserver

为什么要图片懒加载?

进入某个页面时,会有很多图片,有些图片是在下面的,当我们没有滑动到下面时,那些图片还不需要加载的。如果我们加载了也是白加载,这样只会降低网页的加载速度。所以我们需要懒加载,只有滑动到可视区域才会加载当前需要的图片。

实现原理

图片的加载是由src的值引起的,当对src赋值时浏览器就会请求图片资源。我们可以使用html5的自定义属性data-xxx(data-src)来保存真实的路径,当需要加载时(到达可视区域),才将data-xxx的值赋给src

  1. 图片还没在可视区域时(data-xxx保存真实路径)

在这里插入图片描述

  1. 图片在可视区域时(将data-xxx的值赋予src)
    在这里插入图片描述

如何判断是否在可视区域

图片距离视窗顶部的距离(getBoundingClientRect().top)小于窗口显示区的高度(window.innerHeight),就在可视区域,如下图蓝色图片。
在这里插入图片描述

具体实现代码

<body>
    <div>你好你好</div>
    <div>你好你好</div>
    <div>你好你好</div>
    <div>你好你好</div>
    <div>你好你好</div>
    <div>你好你好</div>
    <img style="margin-left: 30%;margin-top: 50px;margin-bottom: 50px;"
        data-src="1.webp" alt="">
    <img style="margin-left: 30%;margin-top: 50px;margin-bottom: 50px;"
        data-src="2.webp" alt="">
    <img style="margin-left: 30%;margin-top: 50px;margin-bottom: 50px;"
        data-src="3.webp"
        alt="">
    <div>你好你好</div>
    <div>你好你好</div>
    <div>你好你好</div>
    <div>你好你好</div>
</body>


<style>
    div {
        height: 350px;
        font-size: 50px;
        margin: 0 30%;

    }
</style>

Script部分
事件监听scroll滚动事件,获取每张图片距离视窗顶部的距离(设置为a)和窗口显示区的高度(设置为b)

如果a<b, 就在可视区域内,就将data_src的值赋予src

这样就可以实现图片懒加载。

    const images = document.querySelectorAll('img');
    window.addEventListener('scroll', (e) => {
        images.forEach(image => {
            const imageTop = image.getBoundingClientRect().top;
            if (imageTop < window.innerHeight) {
                const data_src = image.getAttribute('data-src');
                image.setAttribute('src', data_src);
                console.log('scroll触发了')
            }
        });
    })

上面的代码,滚动事件会被触发很多次,而且图片已经加载了还是会触发滚动事件,非常消耗资源
在这里插入图片描述

最佳解决方法

因此,目前最推荐使用的还是IntersectionObserver

IntersectionObserver是浏览器提供的构造函数(有些浏览器不支持)

IntersectionObserver实例有两个方法,observe(观察一个节点)和unobserve(解除观察)

实例传入一个参数,是回调函数,目标元素(图片)看见了触发一次,看不见也触发一次
在这里插入图片描述
这个回调函数接收一个数组参数,数组的每一项都有isIntersecting属性,代表是否在可视区域;而target代表着目标元素

所以当isIntersectingtrue时,就将这个元素的data_src的值赋予src
然后再解除对这张图片的观察,事件只会被触发3次
在这里插入图片描述
代码如下:

<script>

// 使用IntersectionObserver构造函数
    // IntersectionObserver实例有两个方法,observe(观察一个节点)和unobserve(解除观察)
    const images = document.querySelectorAll('img');
    const callback = (entries) => {
        entries.forEach(entry => {
            // 每个entry数组都有一个isIntersecting属性(是否在可视区域)
            if (entry.isIntersecting) {
                // target代表着目标元素
                const image = entry.target;
                const data_src = image.getAttribute('data-src');
                image.setAttribute('src', data_src);
                observer.unobserve(image);
                console.log('触发了')
            }
        })
    }
    const observer = new IntersectionObserver(callback);
    images.forEach(image => {
        observer.observe(image);
    })
</script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值