Image preload图片预加载,懒加载

有时候因为网络卡或者图片太大加载比较慢,这样图片就会出现无法加载,一般都是希望先显示一张图片加载中或者显示其他图片,那么这个就是图片的预加载或者懒加载。

1.以下来说说Jquery图片的预加载Image preload,加载完后执行Alert提醒,可以自定义为自己的处理函数:

<img src="http://img01.taobaocdn.com/imgextra/i1/397746073/T2BDE8Xb0bXXXXXXXX-397746073.jpg"/>
<input type="button" value="loadImg" onclick = "loadImage('http://img01.taobaocdn.com/imgextra/i1/397746073/T2BDE8Xb0bXXXXXXXX-397746073.jpg',imgLoad)">
<script>
function loadImage(url,callback) {
    var img = new Image();

    img.src = url;

    if(img.complete) {  // 如果图片已经存在于浏览器缓存,直接调用回调函数

        callback.call(img);
        return; // 直接返回,不用再处理onload事件
    }

    img.onload = function(){
        img.onload = null;
        callback.call(img);
    }
}
function imgLoad(){
        alert(this.width);
}
</script>

2.有时候图片还没加载完成的话,我们需要让图片显示一张正在加载中,加载完后再替换的情况:

<img id="myImage" src="images/modxsheet1.png">
<script type="text/javascript">
$(function(){ 
    $('#myImage').attr('src', 'http://img.aipaike.com//group1/M00/0C/79/Cvv7ZVdyJneANc73AAO5i6uQbvA283_300x300.jpg').load(function() {
        alert('Image Loaded');
    });
}); 
</script>

3.在懒加载/延迟加载的时候,有可能我们需要先获取图片宽高,但是不需要马上显示,这是就需要预加载图片取得宽高了,以下代码是一个帅鸽写的函数:

<script type="text/javascript">
var imgReady = (function(){
    var list = [],
        intervalId = null;

    // 用来执行队列
    var queue = function(){

        for(var i = 0; i < list.length; i++){
            list[i].end ? list.splice(i--,1) : list[i]();
        }
        !list.length && stop();
    };

    // 停止所有定时器队列
    var stop = function(){
        clearInterval(intervalId);
        intervalId = null;
    }
    return function(url, ready, error) {
        var onready = {}, 
            width, 
            height, 
            newWidth, 
            newHeight,
            img = new Image();
        img.src = url;

        // 如果图片被缓存,则直接返回缓存数据
        if(img.complete) {
            ready.call(img);
            return;
        }
        width = img.width;
        height = img.height;

        // 加载错误后的事件 
        img.onerror = function () {
            error && error.call(img);
            onready.end = true;
            img = img.onload = img.onerror = null;
        };

        // 图片尺寸就绪
        var onready = function() {
            newWidth = img.width;
            newHeight = img.height;
            if (newWidth !== width || newHeight !== height ||
                // 如果图片已经在其他地方加载可使用面积检测
                newWidth * newHeight > 1024
            ) {
                ready.call(img);
                onready.end = true;
            };
        };
        onready();
        // 完全加载完毕的事件
        img.onload = function () {
            // onload在定时器时间差范围内可能比onready快
            // 这里进行检查并保证onready优先执行
            !onready.end && onready();
            // IE gif动画会循环执行onload,置空onload即可
            img = img.onload = img.onerror = null;
        };


        // 加入队列中定期执行
        if (!onready.end) {
            list.push(onready);
            // 无论何时只允许出现一个定时器,减少浏览器性能损耗
            if (intervalId === null) {
                intervalId = setInterval(queue, 40);
            };
        };
    }
})();
imgReady('http://img01.taobaocdn.com/imgextra/i1/397746073/T2BDE8Xb0bXXXXXXXX-397746073.jpg',function(){
    alert('width:' + this.width + 'height:' + this.height);
});
</script>

4.有些情况,网页显示的图片很多,而且是多屏的,比如像淘宝京东之类的商城,但是为了节省服务器的请求次数和资源消耗,使用了懒加载/延迟加载方式,把一整页的图片分屏显示,当用户滚动到指定屏幕或高度的时候才显示该范围内的图片,以此节省资源,以下网罗的延迟加载类:

 //
 // JS图片延迟加载
 // @constructor {DataLazyLoad}
 // @param {options} 对象传参
 // @time 2014-1-10
 //
 //
 // 延迟加载的原理:滚动时:待加载的资源相对于游览器顶端的距离 - threshold <= 可视区域相对于浏览器顶端的距离 true 就加载
 // 否则的话 不加载
 //
 function DataLazyLoad(options){
    
    this.config = {

        container      :   window,   //容器 默认为window
        threshold      :   0,        // 离多少像素渲染图片
        event          :  'scroll',  // 默认为scroll(滚动)
        effect         :  'fadeIn',  // 默认为fadeIn 也可以为fadeIn, slideDown 等 jQuery 自带的效果
        effectspeed    :  1000,      // 时间  
        suffix         :  'img',     // img属性 默认以data-img 也可以自定义后缀
        skip_invisible : true       // 如果img标签为隐藏的 那么不强制加载
    };

    this.cache = {};

    this.init(options);
 }
 
 DataLazyLoad.prototype = {
    
    init: function(options){
        
        this.config = $.extend(this.config, options || {});
        var self = this,
            _config = self.config,
            _cache = self.cache;
        
        // 滚动时(或者其他事件) 触发事件
        $(_config.container).unbind(_config.event);
        $(_config.container).bind(_config.event,function(){
            self._update();
        });
    },
     //
     // 加载对应的图片
     //
    _eachImg: function(item) {
        var self = this,
            _config = self.config,
            _cache = self.cache;
        
        if($(item).attr('isload') == 'false') {
            var dataImg = $(item).attr('data-'+_config.suffix),
                src = $(item).attr('src');
             $(item).hide();
             $(item).attr('src',dataImg);
             $(item).attr('data-'+_config.suffix,'');
             $(item)[_config.effect](_config.effectspeed);
             $(item).attr('isload','true');
        } 
    },
    _update:function(){
        var self = this,
            _config = self.config,
            _cache = self.cache;
         if(_config.container === window) {
             
             $('img').each(function(index,item){
                // 如果图片隐藏的 那么不强制加载
                if(_config.skip_invisible && !$('img').is(":visible")) {
                    return;
                }
                if (self._abovethetop(item) ||
                    self._leftofbegin(item)) {
                        // 什么都不处理
                } else if (self._belowthefold(item) &&
                    self._belowthefold(item)) {
                        self._eachImg(item);
                } 
            })
            
         }else {
            $('img',$(_config.container)).each(function(index,item){
                // 如果图片隐藏的 那么不强制加载
                if(_config.skip_invisible && !$('img').is(":visible")) {
                    return;
                }
                if (self._abovethetop(item) ||
                    self._leftofbegin(item)) {
                        
                } else if (self._belowthefold(item) &&
                    self._rightoffold(item)) {
                        self._eachImg(item);
                } 

            })
         }
         
    },
     //
     // 往下滚动时 判断待加载的元素是否在可视区域内
     // @return {Boolean}
     //
    _belowthefold: function(elem){
        var self = this,
            _config = self.config;
        var fold;
        if(_config.container === window) {
            fold = $(window).height() + $(window).scrollTop();
        }else {
            fold = $(_config.container).offset().top + $(_config.container).height();
        }

        return fold >= $(elem).offset().top - _config.threshold;
    },
    // 
    // 往右滚动时 判断待加载的元素是否在可视区域内
    // @return {Boolean}
    //
    _rightoffold: function(elem){
        var self = this,
            _config = self.config;
        var fold;
        if(_config.container === window) {
            fold = $(window).width() + $(window).scrollLeft();
        }else {
            fold = $(_config.container).offset().left + $(_config.container).width();
        }
        
        return fold >= $(elem).offset().left - _config.threshold;
    },
     //
     // 往上滚动
     // @return {Boolean}
     //
    _abovethetop: function(elem){
        var self = this,
            _config = self.config;
        var fold;
        if(_config.container === window) {
            fold = $(window).scrollTop();
        }else {
            fold = $(_config.container).offset().top;
        }
        return fold >= $(elem).offset().top + _config.threshold  + $(elem).height();
    },
    //
    //  往左滚动
    // @return {Boolean}
    //
    _leftofbegin: function(elem) {
        var self = this,
            _config = self.config;
        var fold;
        
        if (_config.container === window) {
            fold = $(window).scrollLeft();
        } else {
            fold = $(_config.container).offset().left;
        }
        return fold >= $(elem).offset().left + _config.threshold + $(elem).width();
    }
    
 };

 // 初始化的方式
 $(function(){
    
    var datalazy = new DataLazyLoad({
        container: '#demo'
    });
 });

Jquery插件:http://www.cnblogs.com/aaronguo/p/5257659.html

 

 

0 Comments

Leave a comment