什么是图片惰性加载呢?
顾名思义,惰性指的是我们只将用户视野范围内(浏览器窗口的可视区域)的图片加载,而用户视野范围外的图片先不加载,当用户看到这些图片时再做加载。
这样做的好处在于哪里呢?

  1. 用户访问速度上升了,浏览器的加载进度条很快就加载完毕。
  2. 节省用户流量。

那么如何实现呢?
我们需要解决两个问题:

  1. 如何知道用户是否能看见这张图片?
  2. 如何让看不到的图片不加载,而在需要的时候再去加载?

先解决第一个问题:如何知道用户是否能看见这张图片?
首先需要获取三个值,这些都可以通过javascript获取。

  1. 浏览器窗口的高度 windowHeight
  2. 页面滚动的距离 windowPageY
  3. 图片距离页面顶部的距离 imgTop

if(imgTop >= windowPageY && imgTop <= (windowPageY+windowHeight)){ //图片可见 }

关于上面的条件判断,相信你仔细思考就能看明白。
解决第二个问题:如何让看不到的图片不加载,而在需要的时候再去加载?
所有图片元素的src值先设置为一个很小的图片或者一张“加载中”的图片,而它的真实属性放置在一个自定义属性中如:

<img data-src="真实大图.png" src="小图.png">
这样浏览器只会去加载小图,而不会去加载大图,而当你所有图片都用同一张小图的时候,这张小图只需要加载一次,所以速度非常快。
当这张图片需要加载了,那么我们只需要将原先放置在自定义属性中的图片地址放置到img标签额src属性中就可以了,接下来浏览器就会去请求并加载这张图片:
基本原理就是这样,代码细节就不赘述了,代码如下:

(function(){
  /**
  * 功能:图片惰性加载。在需要图片惰性加载的页面底部载入。再将图片加上class=“lazy”。并将图片的真实地址放置在图片的自定义属性data-src中。
  */
  var lazyLoad = {
init: function() {
    var that = this;
    that.onerrorImgUrl = "./images/grey.png";//图片加载失败用什么图片替换
    that.srcStore      = "data-src";   //图片真实地址存放的自定义属性
    that.class         = "lazy";      //惰性加载的图片需要添加的class
    that.sensitivity   = 50;           //该值越小,惰性越强(加载越少)      
    
    minScroll = 5,
    slowScrollTime = 200,
    ios = navigator.appVersion.match(/(iPhone\sOS)\s([\d_]+)/),
    isIos = ios && !0 || !1,
    isoVersion = isIos && ios[2].split("_");

    isoVersion = isoVersion && parseFloat(isoVersion.length > 1 ? isoVersion.splice(0, 2).join(".") : isoVersion[0], 10),
    isIos = that.isPhone = isIos && isoVersion < 6;
    
    if (isIos) {
        
        var startSyAndTime,
        setTimeOut;
        $(window).on("touchstart",function() {
            startSyAndTime = {
                sy: window.scrollY,
                time: Date.now()
            },
            setTimeOut && clearTimeout(setTimeOut)
        }).on("touchend",function(e) {
            if (e && e.changedTouches) {
                var subtractionY = Math.abs(window.scrollY - startSyAndTime.sy);
                if (subtractionY > minScroll) {
                    var subtractionTime = Date.now() - startSyAndTime.time;
                    setTimeOut = setTimeout(function() {
                        that.changeimg(),
                        startSyAndTime = {},
                        clearTimeout(setTimeOut),
                        setTimeOut = null
                    },
                    subtractionTime > slowScrollTime ? 0: 200)
                }
            } else {
                that.changeimg();
            }
        }).on("touchcancel", function() {
            setTimeOut && clearTimeout(setTimeOut),
            startSyAndTime = {}
        })
    } else {
        $(window).on("scroll", function() {
            that.changeimg();
        });
    }
    setTimeout(function() {
        that.trigger();             
    },90);
    
},
trigger: function() {
    var that = this;
    eventType = that.isPhone && "touchend" || "scroll";
    that.imglist = $('img.'+that.class+'');
    $(window).trigger(eventType);
},
changeimg: function() {
    function loadYesOrno(img) {
        var windowPageYOffset = window.pageYOffset,
        windowPageYOffsetAddHeight = windowPageYOffset + window.innerHeight,
        imgOffsetTop = img.offset().top;
        return imgOffsetTop >= windowPageYOffset && imgOffsetTop - that.sensitivity <= windowPageYOffsetAddHeight;
    }
    function loadImg(img, index) {
        
        var imgUrl = img.attr(that.srcStore);
        img.attr("src", imgUrl);
        img[0].onload || (img[0].onload = function() {
            $(this).removeClass(that.class).removeAttr(that.srcStore),
            that.imglist[index] = null,
            this.onerror = this.onload = null
        },
        img[0].onerror = function() {
            this.src = that.onerrorImgUrl,
            $(this).removeClass(that.class).removeAttr(that.srcStore),
            that.imglist[index] = null,
            this.onerror = this.onload = null
        })
    }
    var that = this;
    that.imglist.each(function(index, val) {
        if (!val) return;
        var img = $(val);
        if (!loadYesOrno(img)) return;
        if (!img.attr(that.srcStore)) return;
        loadImg(img, index);
    })
    
}
};
lazyLoad.init();

}());

在页面底部载入jQuery或Zepto,然后载入上面的代码就OK了