图片懒加载的实现

522 阅读1分钟
  1. Element.getBoundingClientRect()  方法返回元素的大小及其相对于视口的位置。如果是标准盒子模型,元素的尺寸等于width/height + padding + border-width的总和。如果box-sizing: border-box,元素的的尺寸等于 width/height
  2. 实现思路很简单,就是html里面的img标签的src属性先不写如地址,将地址存在其他属性里面。当图片进入视口时候,将图片的地址写入src属性
  3. 代码里面还添加了一个节流函数,防止多次操作
```
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        div,img{
            height: 300px;
        }
    </style>
</head>
<body>
<div>
    <img src="" alt="" data-img="https://gimg2.baidu.com/image_search/src=http%3A%2F%2F2c.zol-img.com.cn%2Fproduct%2F124_500x2000%2F748%2FceZOdKgDAFsq2.jpg&refer=http%3A%2F%2F2c.zol-img.com.cn&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1629826287&t=cc451541ab91ab763d9d0b8afc97b756">
</div>
<div>
    <img src="" alt="" data-img="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fgss0.baidu.com%2F-Po3dSag_xI4khGko9WTAnF6hhy%2Fzhidao%2Fpic%2Fitem%2F4034970a304e251fae75ad03a786c9177e3e534e.jpg&refer=http%3A%2F%2Fgss0.baidu.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1629826346&t=77b192214904fca03a02dc4af5d4b2ab">
</div>
<div>
    <img src="" alt="" data-img="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fphoto.tuchong.com%2F3818889%2Ff%2F1195841456.jpg&refer=http%3A%2F%2Fphoto.tuchong.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1629826346&t=a5f2564045d6d49b98b549b24ff52ed7">
</div>
<div>
    <img src="" alt="" data-img="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fcdn.duitang.com%2Fuploads%2Fblog%2F201306%2F25%2F20130625150506_fiJ2r.jpeg&refer=http%3A%2F%2Fcdn.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1629826346&t=29748ef4baa6a5e1af30ca543b49904e">
</div>
<div>
    <img src="" alt="" data-img="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg.pconline.com.cn%2Fimages%2Fupload%2Fupc%2Ftx%2Fphotoblog%2F1210%2F26%2Fc2%2F14676275_14676275_1351218242935_mthumb.jpg&refer=http%3A%2F%2Fimg.pconline.com.cn&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1629826346&t=c5d6040cbdae338d0ad3298bc47e097e">
</div>
<div>
    <img src="" alt="" data-img="https://gimg2.baidu.com/image_search/src=http%3A%2F%2F2c.zol-img.com.cn%2Fproduct%2F124_500x2000%2F748%2FceZOdKgDAFsq2.jpg&refer=http%3A%2F%2F2c.zol-img.com.cn&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1629826287&t=cc451541ab91ab763d9d0b8afc97b756">
</div>
<div>
    <img src="" alt="" data-img="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fgss0.baidu.com%2F-Po3dSag_xI4khGko9WTAnF6hhy%2Fzhidao%2Fpic%2Fitem%2F4034970a304e251fae75ad03a786c9177e3e534e.jpg&refer=http%3A%2F%2Fgss0.baidu.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1629826346&t=77b192214904fca03a02dc4af5d4b2ab">
</div>
<div>
    <img src="" alt="" data-img="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fphoto.tuchong.com%2F3818889%2Ff%2F1195841456.jpg&refer=http%3A%2F%2Fphoto.tuchong.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1629826346&t=a5f2564045d6d49b98b549b24ff52ed7">
</div>
<div>
    <img src="" alt="" data-img="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fcdn.duitang.com%2Fuploads%2Fblog%2F201306%2F25%2F20130625150506_fiJ2r.jpeg&refer=http%3A%2F%2Fcdn.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1629826346&t=29748ef4baa6a5e1af30ca543b49904e">
</div>
<div>
    <img src="" alt="" data-img="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg.pconline.com.cn%2Fimages%2Fupload%2Fupc%2Ftx%2Fphotoblog%2F1210%2F26%2Fc2%2F14676275_14676275_1351218242935_mthumb.jpg&refer=http%3A%2F%2Fimg.pconline.com.cn&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1629826346&t=c5d6040cbdae338d0ad3298bc47e097e">
</div>
<script>
    let imgList = [...document.querySelectorAll('img')]
    let length = imgList.length

    // 节流函数
    function throttle(fn, wait){
        let timer = null
        return function () {
            if(!timer){
                fn.call(this)
            }
            timer = setTimeout(() => {
                timer = null
            }, wait)
        }
    }

    // 懒加载函数
    const imgLazyLoad = (function () {
        // 计数器,当所有图片都加载完成后,清除图片懒加载的监听
        let count = 0
        return function () {
            // 当前懒加载被加载的图片后续就不需要加载了
            let deleteIndexList = []
            imgList.forEach((img, index) => {
                let rect = img.getBoundingClientRect()
                if (rect.top < window.innerHeight) {
                    img.src = img.getAttribute('data-img')
                    deleteIndexList.push(index)
                    count++
                    if (count === length) {
                        document.removeEventListener('scroll', imgLazyLoad)
                    }
                }
            })
            // 将被加载的图片移除(应该不能说被加载,是地址从data-img属性移入src属性)
            imgList = imgList.filter((img, index) => !deleteIndexList.includes(index))
        }
    })()
    // 第一次自调用是为了处理打开时候就在视口里面的图片的显示
    imgLazyLoad()

    document.addEventListener('scroll', throttle(imgLazyLoad, 100))

</script>
</body>
</html>
```