三种懒加载方式及对比

利用getBoundingClientRect

  • 优点:容易理解,操作easy

  • 缺点:只能用于全屏滚动的列表,不适用于局部滚动,譬如下图

snipaste_20230214_225429.png


<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        #box{
            height: 300px;
            overflow: scroll;
        }
        img {
            width: 100%;
        }
    </style>
</head>

<body>
    <div id="box">
        <img src="./213.jpg"
            data-src="https://img1.baidu.com/it/u=2490614914,3569829953&fm=253&fmt=auto&app=138&f=JPEG?w=591&h=500"
            alt="">
        <img src="./213.jpg"
            data-src="https://img1.baidu.com/it/u=2490614914,3569829953&fm=253&fmt=auto&app=138&f=JPEG?w=591&h=500"
            alt="">
        <img src="./213.jpg"
            data-src="https://img1.baidu.com/it/u=2490614914,3569829953&fm=253&fmt=auto&app=138&f=JPEG?w=591&h=500"
            alt="">
        <img src="./213.jpg"
            data-src="https://img1.baidu.com/it/u=2490614914,3569829953&fm=253&fmt=auto&app=138&f=JPEG?w=591&h=500"
            alt="">
        <img src="./213.jpg"
            data-src="https://img1.baidu.com/it/u=2490614914,3569829953&fm=253&fmt=auto&app=138&f=JPEG?w=591&h=500"
            alt="">
        <img src="./213.jpg"
            data-src="https://img1.baidu.com/it/u=2490614914,3569829953&fm=253&fmt=auto&app=138&f=JPEG?w=591&h=500"
            alt="">
        <img src="./213.jpg"
            data-src="https://img1.baidu.com/it/u=2490614914,3569829953&fm=253&fmt=auto&app=138&f=JPEG?w=591&h=500"
            alt="">
    </div>
</body>
<script>
    window.onload = function () {
        let box = document.getElementById('box')
        let img = [...document.querySelectorAll('img')]
        box.onscroll=function(){
            lazyLoad()
        }
        lazyLoad()
        function lazyLoad(){
            for(let i = 0;i<img.length;i++){
                let {top,bottom} = img[i].getBoundingClientRect()
                // 判断是否在box显示界限内
                if(top>0&&bottom<box.offsetHeight+img[i].offsetHeight/2){
                    console.log(top,bottom)
                    img[i].src = img[i].dataset.src
                    img.splice(i,1)
                    i--
                }
            }
        }
    }
</script>

</html>

利用api IntersectionObserver

优点:容易使用,适用于各种场景

缺点:兼容性不是很好

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        #box{
            height: 300px;
            overflow: scroll;
        }
        img {
            width: 100%;
        }
    </style>
</head>

<body>
    <div id="box">
        <img src="./213.jpg"
            data-src="https://img1.baidu.com/it/u=2490614914,3569829953&fm=253&fmt=auto&app=138&f=JPEG?w=591&h=500"
            alt="">
        <img src="./213.jpg"
            data-src="https://img1.baidu.com/it/u=2490614914,3569829953&fm=253&fmt=auto&app=138&f=JPEG?w=591&h=500"
            alt="">
        <img src="./213.jpg"
            data-src="https://img1.baidu.com/it/u=2490614914,3569829953&fm=253&fmt=auto&app=138&f=JPEG?w=591&h=500"
            alt="">
        <img src="./213.jpg"
            data-src="https://img1.baidu.com/it/u=2490614914,3569829953&fm=253&fmt=auto&app=138&f=JPEG?w=591&h=500"
            alt="">
        <img src="./213.jpg"
            data-src="https://img1.baidu.com/it/u=2490614914,3569829953&fm=253&fmt=auto&app=138&f=JPEG?w=591&h=500"
            alt="">
        <img src="./213.jpg"
            data-src="https://img1.baidu.com/it/u=2490614914,3569829953&fm=253&fmt=auto&app=138&f=JPEG?w=591&h=500"
            alt="">
        <img src="./213.jpg"
            data-src="https://img1.baidu.com/it/u=2490614914,3569829953&fm=253&fmt=auto&app=138&f=JPEG?w=591&h=500"
            alt="">
    </div>
</body>
<script>
    window.onload = function () {
        let box = document.getElementById('box')   
        let img = document.querySelectorAll('img')
        let io = new IntersectionObserver(function (entries) {
            entries.forEach(entry => {
                console.log(entry.intersectionRatio)
                if (entry.intersectionRatio > 0) {
                    entry.target.src = entry.target.dataset.src
                    io.unobserve(entry.target)
                }
            })
        })
        img.forEach(item => {
            io.observe(item)
        })
    }
</script>

</html>

借用offsetTop

  • 优点:适用各种情况
  • 缺点:需要对原生代码熟悉,过后容易忘记
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        #box{
            height: 300px;
            overflow: scroll;
            position: relative;
        }
        img {
            width: 100%;
        }
    </style>
</head>

<body>
    <div style="height: 300px;width: 200px;"></div>
    <div id="box">
        <img src="./213.jpg"
            data-src="https://img1.baidu.com/it/u=2490614914,3569829953&fm=253&fmt=auto&app=138&f=JPEG?w=591&h=500"
            alt="">
        <img src="./213.jpg"
            data-src="https://img1.baidu.com/it/u=2490614914,3569829953&fm=253&fmt=auto&app=138&f=JPEG?w=591&h=500"
            alt="">
        <img src="./213.jpg"
            data-src="https://img1.baidu.com/it/u=2490614914,3569829953&fm=253&fmt=auto&app=138&f=JPEG?w=591&h=500"
            alt="">
        <img src="./213.jpg"
            data-src="https://img1.baidu.com/it/u=2490614914,3569829953&fm=253&fmt=auto&app=138&f=JPEG?w=591&h=500"
            alt="">
        <img src="./213.jpg"
            data-src="https://img1.baidu.com/it/u=2490614914,3569829953&fm=253&fmt=auto&app=138&f=JPEG?w=591&h=500"
            alt="">
        <img src="./213.jpg"
            data-src="https://img1.baidu.com/it/u=2490614914,3569829953&fm=253&fmt=auto&app=138&f=JPEG?w=591&h=500"
            alt="">
        <img src="./213.jpg"
            data-src="https://img1.baidu.com/it/u=2490614914,3569829953&fm=253&fmt=auto&app=138&f=JPEG?w=591&h=500"
            alt="">
    </div>
</body>
<script>
    window.onload = function () {
        let box = document.getElementById('box')
        let img = [...document.querySelectorAll('img')]
        box.onscroll=function(){
            lazyLoad()
        }
        lazyLoad()
        function lazyLoad(){
            for(let i = 0;i<img.length;i++){
                // 记得父元素需要设置定位
                let offsetTop = img[i].offsetTop
                if(box.scrollTop+box.offsetHeight/2>=offsetTop){
                    img[i].src = img[i].dataset.src
                    img.splice(i,1)
                    i--
                }
            }
        }
        
    }
</script>

</html>
posted @ 2023-02-14 23:01  Monday1997  阅读(57)  评论(0编辑  收藏  举报