图片懒加载

(原创不易,转载请标明出处,谢谢)

应用场景及背景介绍:

某一页面有大量图片。如果一开始全部加载,则同时请求较多的网络资源,页面会出现很长一段时间的空白,用户体验很不好,所以需要图片懒加载。

图片懒加载原理

  1. 所有图片地址src,先设置为某一图片,这样只会请求一次网络资源
  2. 当所需要的图片进入浏览器窗口视野之后,将图片地址src替换为真实的图片地址。

演示效果

https://codepen.io/lilylaw/pen/XWbxxNO

代码

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title></title>
        <style>
            *{
                margin: 0;
                padding: 0;
            }
            .wrap{
                width: 800px;
                margin: auto;
                display: flex;
                flex-wrap: wrap;
            }
            .wrap img{
                width: 50%;
                height: auto;
            }
        </style>
    </head>
    <body>
        <div class="wrap">
            
        </div>
        
        <script>
            let imgs = [
                "http://seopic.699pic.com/photo/50156/2840.jpg_wh1200.jpg",
                "http://seopic.699pic.com/photo/50148/0957.jpg_wh1200.jpg",
                "http://seopic.699pic.com/photo/50146/0835.jpg_wh1200.jpg",
                "http://seopic.699pic.com/photo/50021/1012.jpg_wh1200.jpg",
                "http://seopic.699pic.com/photo/50127/5145.jpg_wh1200.jpg",
                "http://seopic.699pic.com/photo/50122/4249.jpg_wh1200.jpg",
                "http://seopic.699pic.com/photo/50041/6637.jpg_wh1200.jpg",
                "http://seopic.699pic.com/photo/50085/0650.jpg_wh1200.jpg",
                "http://seopic.699pic.com/photo/50120/4383.jpg_wh1200.jpg",
                "http://seopic.699pic.com/photo/50035/4345.jpg_wh1200.jpg",
                "http://seopic.699pic.com/photo/50119/3443.jpg_wh1200.jpg",
                "http://seopic.699pic.com/photo/50075/8488.jpg_wh1200.jpg",
                "http://seopic.699pic.com/photo/50087/0693.jpg_wh1200.jpg",
                "http://seopic.699pic.com/photo/50154/8480.jpg_wh1200.jpg",
                "http://seopic.699pic.com/photo/50063/0660.jpg_wh1200.jpg",
                "http://seopic.699pic.com/photo/50046/2788.jpg_wh1200.jpg",
                "http://seopic.699pic.com/photo/50070/7820.jpg_wh1200.jpg",
                "http://seopic.699pic.com/photo/50025/5275.jpg_wh1200.jpg",
                "http://seopic.699pic.com/photo/50025/1819.jpg_wh1200.jpg",
                "http://seopic.699pic.com/photo/50036/1958.jpg_wh1200.jpg"
            ];
            
            let wh = window.innerHeight;
            let img = new Image();
            img.src = 'http://img.zcool.cn/community/011546554b9ab1000001bf729a84ca.jpg';
            img.onload = function(){    // 预置的这张图片,必须加载完才能进行下面的操作
                renderImgArr();
                renderRealImg();
            }
            
            window.addEventListener('scroll',()=>{  // 添加监听事件
                renderRealImg();
            });
            
            function renderImgArr(){    // 渲染dom,且将所有图片的src,都先设置为  预置的图片
                let nodelist = []
                for(i in imgs){
                    let tmp = `<img class='eimg' src='http://img.zcool.cn/community/011546554b9ab1000001bf729a84ca.jpg' data-src='`+ imgs[i] +`' />`;
                    nodelist.push(tmp);
                }
                let _html = nodelist.join('');
                let wrap = document.getElementsByClassName('wrap')[0];
                wrap.innerHTML = _html;
            }
            
            function renderRealImg(){   // 渲染真实图片
                let imgNodes = g('.eimg');
                for(let i = 0 ; i < imgNodes.length; i++){
                    // 先检测有没有已被加载的属性
                    if(!imgNodes[i].getAttribute('loaded')){    // 如果已经被设置成真实图片,则不必重复加载
                        // 再检测到窗口的位置
                        if(wh>= (imgNodes[i].offsetTop - window.pageYOffset)){ // 图片到窗口顶端的距离,小于整个窗口的高度,即这张图出现在窗口视野内。
                            imgNodes[i].setAttribute('src',imgNodes[i].getAttribute('data-src'));
                            imgNodes[i].setAttribute('loaded',true);
                        }else{ // 如果此张图片没有在窗口视野内,那么这张图片之后的图片肯定也不在视野内,所以跳出循环,不必对之后的图片进行检测。
                            break;
                        }
                    }
                }
            }
            
            function g(s){  // .a 或者 #a
                // 以.开头还是以#开头
                let method = /\./.test(s) ? 'getElementsByClassName' : 'getElementById';
                return document[method](s.substr(1));
            }
        </script>
    </body>
</html>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容