JavaScript设置首屏图片延时加载的实现和原理

Javascript Lazyload延迟加载特效,有效降低HTPP连接次数,提高首屏加载时间

  • 1、增加了图片预加载可选
  • 2、修改了图片本身就在可视范围的时候直接显示而不需要滚动条触发
  • 3、修改了Splice删除数组的时候,会跳过下一张图片BUG
  • 4、浏览器窗口resize的时候图片出现也会加载
  • 5、判断图片父层包裹顶部或者底部出现在可视范围内即可显示图片

~~~

主要代码如下:

var Lazy = {
        $:function(arg,context){
            var tagAll,n,eles=[],i,sub = arg.substring(1);
            context = context|| document;
            if(typeof arg =='string'){
                switch(arg.charAt(0)){
                    case '#':
                        return document.getElementById(sub);
                        break;
                    case '.':
                        if(context.getElementsByClassName) return context.getElementsByClassName(sub);
                        tagAll = Lazy.$('*');
                        n = tagAll.length;
                        for(i = 0;i<n;i++){
                            if(tagAll[i].className.indexOf(sub) > -1) eles.push(tagAll[i]);
                        }
                        return eles;
                        break;
                    default:
                        return context.getElementsByTagName(arg);
                        break;
                }
            }
        },
        getPos:function (node) {
            var scrollx = document.documentElement.scrollLeft || document.body.scrollLeft,
                    scrollt = document.documentElement.scrollTop || document.body.scrollTop;
            var pos = node.getBoundingClientRect();
            return {top:pos.top + scrollt, right:pos.right + scrollx, bottom:pos.bottom + scrollt, left:pos.left + scrollx }
        },
        bind:function(node,type,handler){
            node.addEventListener?node.addEventListener(type, handler, false):node.attachEvent('on'+ type, handler);
        },
        unbind:function(node,type,handler){
            node.removeEventListener?node.removeEventListener(type, handler, false):node.detachEvent('on'+ type, handler);
        },
        toArray:function(eles){
            var arr = [];
            for(var i=0,n=eles.length;i<n;i++){
                arr.push(eles[i]);
            }
            return arr;
        }
    };
    function imgLazyLoad(){
        var timer,screenHeight = document.documentElement.clientHeight;
        // 选择所有图片
        var allimg = Lazy.$('img');
        // 筛选CLASS为lazyload的图片
        var elems = Lazy.$('.lazyload',allimg);
        // 转换为真正的数组
        elems = Lazy.toArray(elems);
        if(!elems.length) return;
        // 没有发生滚动事件时如果图片在可视范围之内,也显示
        for(var i = 0;i < elems.length;i++){
            // 获取图像的父元素即包裹图像的元素,判断图像是否在可视区域即直接判断父元素是否可视
            var parent = elems[i].parentNode;
            var pos = Lazy.getPos(parent);
            var posT = pos.top;
            var posB = pos.bottom;
            // 没有滚动条情况如果距离顶部的距离小于屏幕的高度则赋值SRC
            if(posT < screenHeight){
                elems[i].src = elems[i].getAttribute('data-img');
                // 移除后,数组的长度减一,下一个下标需减一
                elems.splice(i--,1);
            }
        }
        // 绑定scroll事件
        Lazy.bind(window,'scroll',loading);
        Lazy.bind(window,'resize',loading);
        function loading(){
            timer && clearTimeout(timer);
            timer = setTimeout(function(){
                var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
                screenHeight = document.documentElement.clientHeight;
                console.log(111);
                for(var i = 0;i < elems.length;i++){
                    var parent = elems[i].parentNode;
                    var pos = Lazy.getPos(parent);
                    var posT = pos.top;
                    var posB = pos.bottom;
                    var screenTop = screenHeight+scrollTop;
                    // 元素顶部出现在可视区  或者  元素底部出现在可视区
                    if((posT > scrollTop && posT <  screenTop) || (posB > scrollTop && posB < screenTop)){
                        elems[i].src = elems[i].getAttribute('data-img');
                        elems.splice(i--,1);
                    }else{
                        // 去掉以下注释开启图片预加载
                        // new Image().src = elems[i].getAttribute('data-img');
                    }
                }
                if(!elems.length){
                    Lazy.unbind(window,'scroll',loading);
                    Lazy.unbind(window,'resize',loading);
                }
            },300);
        }
    }
    imgLazyLoad();

使用方法:

1、在图片上增加lazyload的类(class=’lazyload’)

2、把真实的图片地址放入自定义属性data-img 中,把图片的SRC属性设置为一个一像素的透明图片,图片需要设置width,height属性,以免布局混乱

如下:

<img data-img="http://farm6.staticflickr.com/5323/7378265586_e12444509d_n.jpg" src="http://images.cnblogs.com/cnblogs_com/NNUF/379856/t_space.gif" width="640" height="480"  alt="" class='lazyload'>

3、在需要延迟加载的页面调用imgLazyLoad()函数;

~~

延时加载目标 #

保证页面打开速度(如果3S内首页打不开,已经算是死亡页面了)

原理 #

  1. 对于首屏中的图片,首先给对应的区域一张默认图占着位置(默认图需要非常的小,一般可以维持在5K以内),当首屏内容都加载完成后再加载真实的图片。
  2. 对于其它屏的图片,也是给一张默认图片占位,当滚动条滚动到对应的区域的时候我们再开始加载真实的图片。
    扩展: 数据的异步加载,开始只把前二屏的数据加载绑定出来,后面的数据不进行处理,当页面滚动条对应区域的时候再重新请求数据,然后绑定渲染数据。

实现1 #

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>图片延迟加载/懒加载</title>
    <style type="text/css">
        * {
            margin: 0;
            padding: 0;
            font-family: 微软雅黑;
            font-size: 14px;
        }

        .banner {
            margin: 10px auto;
            width: 790px;
            height: 340px;
            border: 1px solid green;
            background: url(default.jpg) no-repeat center center #e1e1e1;
        }

        .banner img {
            display: none;
            width: 100%;
            height: 100%;
        }
    </style>
</head>
<body>
<div class="banner">
    <img id="jd" trueImg="jd2.jpg" src="" alt="">
</div>
<script>
    window.onload = function () {
        var banner = document.getElementById('banner');
        var jd = document.getElementById('jd');
        jd.src = jd.getAttribute('trueImg');
        jd.onload = function () {
            jd.trueImg = '';
            jd.style.display = 'block';
        }
        jd.onerror = function(){
            console.log('error');
        }
    }
</script>
</body>
</html>

实现2 #

window.onload = function () {
    /*var oImg = document.createElement('img');*/
    var jd = document.getElementById('jd');
    var src = jd.getAttribute('trueImg');
    var oImg = new Image();
    oImg.src = src;
    //图片能够正常加载
    oImg.onload = function(){
        jd.src = src;
        jd.style.display = 'block';
        oImg = null;
        var nowTime = new Date();
        console.log('图片加载完成,耗时'+(nowTime - time)+' ms');
    }
    console.log('图片加载中......');
    var time = new Date();
}

~~

jquery图片延时加载技术也叫懒加载技术(简称lazyload),它的好处,可提高网站的加载速度,节约带宽,减少服务器压力
使用原则首屏的图片不要使用图片延时加载,为什么这设置,原因很简单,当用户打开网站的时候,网页的首屏图片必须会加载的,如果用户打开网页看到图片还有加载,这样用户体验不好

<script src="jquery.js" type="text/javascript"></script>
<script src="jquery.lazyload.js" type="text/javascript"></script>
<img class="lazy" data-original="img/example.jpg" width="640" height="480">
$(function() {
$("img.lazy").lazyload();
});

~~~

未经允许不得转载:WEB前端开发 » JavaScript设置首屏图片延时加载的实现和原理

赞 (0)