原生js实现图片懒加载

Posted 潮哥

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了原生js实现图片懒加载相关的知识,希望对你有一定的参考价值。

原理:

将页面中的img标签src指向一张小图片或者src为空,然后定义data-src(这个属性可以自定义命名,我自己用data-src)属性指向真实的图片。

src指向一张默认的图片,否则当src为空时也会向服务器发送一次请求。可以指向loading的地址。

代码实现:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>图片懒加载</title>
</head>
<style>
    img{
        width: 100%;
        height: 300px;
    }
</style>
<body>
    <div id="lazyLoad">
        <img src="https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1465559144,776586395&fm=27&gp=0.jpg" data-src="https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1569565431,1808959505&fm=11&gp=0.jpg" alt="">
        <img src="https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1465559144,776586395&fm=27&gp=0.jpg" data-src="https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1569565431,1808959505&fm=11&gp=0.jpg" alt="">
        <img src="https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1465559144,776586395&fm=27&gp=0.jpg" data-src="https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1569565431,1808959505&fm=11&gp=0.jpg" alt="">
        <img src="https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1465559144,776586395&fm=27&gp=0.jpg" data-src="https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1569565431,1808959505&fm=11&gp=0.jpg" alt="">
        <img src="https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1465559144,776586395&fm=27&gp=0.jpg" data-src="https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1569565431,1808959505&fm=11&gp=0.jpg" alt="">
        <img src="https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1465559144,776586395&fm=27&gp=0.jpg" data-src="https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1569565431,1808959505&fm=11&gp=0.jpg" alt="">
        <img src="https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1465559144,776586395&fm=27&gp=0.jpg" data-src="https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1569565431,1808959505&fm=11&gp=0.jpg" alt="">
        <img src="https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1465559144,776586395&fm=27&gp=0.jpg" data-src="https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1569565431,1808959505&fm=11&gp=0.jpg" alt="">
        <img src="https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1465559144,776586395&fm=27&gp=0.jpg" data-src="https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1569565431,1808959505&fm=11&gp=0.jpg" alt="">
        <img src="https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1465559144,776586395&fm=27&gp=0.jpg" data-src="https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1569565431,1808959505&fm=11&gp=0.jpg" alt="">
        <img src="https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1465559144,776586395&fm=27&gp=0.jpg" data-src="https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1569565431,1808959505&fm=11&gp=0.jpg" alt="">
    </div>
</body>
<script>
    window.onload = function(){
        function lazyLoad(){
            var lazyLoadContainer = document.getElementById(lazyLoad);
            var imgLen = lazyLoadContainer.getElementsByTagName(img).length;//如果图片长度不是固定,而是分页请求的话,则放在return函数中
            var imgList = lazyLoadContainer.getElementsByTagName(img);

            var screenW = document.documentElement.clientWidth;

            var count = 0;//统计懒加载多少图片
            return function(){
                console.log(count);
                var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;//兼容不同浏览器
                for(var i = count; i<imgLen; i++){
                    //console.log(‘offsetTop‘, imgList[i].offsetTop);
                    //console.log(‘scrollHeight‘, scrollTop + screenW);
                    if(imgList[i].offsetTop < scrollTop + screenW-300){
                        if(imgList[i].getAttribute(src) === https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1465559144,776586395&fm=27&gp=0.jpg){
                            imgList[i].src = imgList[i].getAttribute(data-src);
                            count += 1;
                        }
                    }
                }
            }
        }
        var useLazyLoad = lazyLoad();
        useLazyLoad();
        //函数节流
        function throttle(action, delay, time){
            var timer, startTime = new Date();
            return function(){
                var context = this, arg = arguments, curTime = new Date();
                if(timer){
                    clearTimeout(timer);
                }
                if(curTime - startTime > time){
                    action.apply(context,arg);
                    startTime = curTime;
                }else{
                    timer = setTimeout(function(){
                        action.apply(context,arg);
                    },delay)
                }
            }
        }

        window.addEventListener(scroll, throttle(useLazyLoad,500,100))
    }
</script>
</html>

函数节流和函数去抖

以下场景往往由于事件频繁被触发,因而频繁执行DOM操作、资源加载等重行为,导致UI停顿甚至浏览器崩溃。

  1. window对象的resize、scroll事件
  2. 拖拽时的mousemove事件
  3. 射击游戏中的mousedown、keydown事件
  4. 文字输入、自动完成的keyup事件

当调用动作n毫秒后,才会执行该动作,若在这n毫秒内又调用此动作则将重新计算执行时间。这种比较适合window的resize事件(函数去抖);实际需求大多为停止改变大小n毫秒后执行后续处理;而其他事件大多的需求是以一定的频率执行后续处理(函数节流)

function debounce(action,delay){//函数去抖
    var timer = null;
    return function(){
        //console.log(‘timer‘,timer)
        if(timer){
            clearTimeout(timer);

        }
        var context = this; arg = arguments;
        timer = setTimeout(function(){
            action.apply(context,arg)
        },delay);
    }
}

function throttle(action, delay, time){//函数节流
    var timer = null, startTime = new Date();
    return function(){
        if(timer){
            clearTimeout(timer);
        }
        var curTime = new Date();
        var context = this, arg = arguments;
        if(curTime - startTime > time){
            action.apply(context,arg);
            startTime = curTime;
        }else{
            timer = setTimeout(function(){
                action.apply(context,arg)//如果直接传arguments,到时打印出来的是undefined
            },delay)
        }
    }
}
var scrollFunc = debounce(function(a){
    console.log(a);
},500);

var scrollThrottle = throttle(function(a){
    console.log(a)
},5000, 1000)
window.onscroll = function(){
    //scrollFunc(22);
    scrollThrottle(88)
}

 

以上是关于原生js实现图片懒加载的主要内容,如果未能解决你的问题,请参考以下文章

原生JS实现图片懒加载之一:Element.getBoundingClientRect()

原生js实现图片懒加载原理

页面性能优化-原生JS实现图片懒加载

原生js实现懒加载并节流

vuevue-cli3构建项目中实现图片懒加载

懒加载和预加载---性能优化