单张图片懒加载案例->两种实现方法

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>单张图片懒加载案例</title>
    <!-- IMPORT CSS -->
    <link rel="stylesheet" href="css/reset.min.css">
    <style>
        html,
        body {
            height: 300%;
        } 
        .lazyImageBox {
            position: absolute;
            left: 50%;
            top: 1500px;
            transform: translateX(-50%);
            width: 400px;
            height: 300px;
            background: url("./images/default.gif") no-repeat center center #EEE;
        }

        .lazyImageBox img {
            width: 100%;
            height: 100%;
            opacity: 0;
            transition: opacity .3s;
        }
    </style>
</head>

<body>
    <!-- 
        图片延迟加载的意义:
          项目中,如果一开始加载页面,就把所有的真实图片也去加载,不论是从网络消耗上,还是从页面渲染上都是非常的消耗性能的,导致加载过慢... 真实开发中,我们一般首次渲染,不去渲染真实的图片,把图片部分用一个默认的盒子占位(有默认的背景图,给用户一种感觉:图片正在加载中)

        把能够出现在当前视口中的图片(它所在的那个占位盒子出现在视口中)做加载
     -->
    <div class="lazyImageBox">
        <img src="" alt="" lazy-image="images/12.jpg">
    </div>

    <!-- IMPORT JS -->
   <!-- <script>

        // 节流函数
        function throttle(func, wait = 500) {
            let timer = null,
                previous = 0;
            return function anonymous(...params) {
                let now = new Date(),
                    remaining = wait - (now - previous);
                if (remaining <= 0) {
                    clearTimeout(timer);
                    timer = null;
                    previous = now;
                    func.call(this, ...params);
                } else if (!timer) {
                    timer = setTimeout(() => {
                        clearTimeout(timer);
                        timer = null;
                        previous = new Date();
                        func.call(this, ...params);
                    }, remaining);
                }
            };
        }


       let lazyImageBox = document.querySelector('.lazyImageBox'),
           lazyImage = lazyImageBox.querySelector('img');

        const singleLazy = function singleLazy(){
            // 获取加载的图片
            let trueImg = lazyImage.getAttribute('lazy-image');
            lazyImage.src = trueImg;
            lazyImage.onload=()=>{
                // 真实图片加载成功
                lazyImage.style.opacity = 1;
                // 加载成功的标记
                lazyImageBox.isLoad = true;
            }
        }

       const lazyFunc = function lazyFunc(){
       
          // 判断如果已经加载成功,  就返回, 防止重复加载
           if(lazyImageBox.isLoad) return ;
           // 获取元素盒子底部距离
            let A = lazyImageBox.getBoundingClientRect().bottom,
            // 获取视口高度
                B = document.documentElement.clientHeight;
            if(A <= B){ 
                // 加载图片
                singleLazy();
            } 
       } 
       setTimeout(lazyFunc,1000);
       //函数节流 
       window.onscroll = throttle(lazyFunc);
    </script>  -->
   
   
    <!-- 第二种实现方法  IntersectionObserver->因为兼容性,所以移动端使用多点 -->
    <script>
        let lazyImageBox = document.querySelector('.lazyImageBox'),
         lazyImage = lazyImageBox.querySelector('img');

        const singleLazy = function singleLazy(){
            // 获取加载的图片
            let trueImg = lazyImage.getAttribute('lazy-image');
            lazyImage.src = trueImg;
            lazyImage.onload=function(){
                // 真实图片加载成功
                lazyImage.style.opacity = 1; 
            }
        }


        // 使用 DOM 监听器 监听, 监听一个或多个
        let ob = new IntersectionObserver(function(changes){
            // console.log(changes);
            // changes 是一个数组,包含所有监听的Dom元素和视口的交叉信息
            let item = changes[0];
            // console.log(item);
            // let {isIntersecting,target} = item; 
            if(item.isIntersecting){
                // 完全出现在视口中  加载图片
                singleLazy();
                // 加载完成后 移除监听
                ob.unobserve(lazyImageBox);
            }
            console.log(item);
        },{
            //  threshold:[0,.5,1]   // 0 显示一部分就触发  1 显示完整才触发
            threshold:[1]
        });
        ob.observe(lazyImageBox);

    </script> 

</body>

</html>
posted @ 2021-08-03 10:46  13522679763-任国强  阅读(57)  评论(0)    收藏  举报