源于生活

标题: JQuery实现图片的预加载与延时加载 [打印本页]

作者: kevin-ying    时间: 2015-8-3 16:03
标题: JQuery实现图片的预加载与延时加载
有很多项目经常会需要判断图片加载完成后执行相应的操作,或者需要图片延迟加载,网上虽然已经有很不错的插件,但要为这些效果还得单独加载一个插件的话总感觉有点不舒服,干脆自己写了个方法:
  1. function loadimg(arr,funLoading,funOnLoad,funOnError){
  2.         var numLoaded=0,
  3.         numError=0,
  4.         isObject=Object.prototype.toString.call(arr)==="[object Object]" ? true : false;

  5.         var arr=isObject ? arr.get() : arr;
  6.         for(a in arr){
  7.                 var src=isObject ? $(arr[a]).attr("data-src") : arr[a];
  8.                 preload(src,arr[a]);
  9.         }

  10.         function preload(src,obj){
  11.                 var img=new Image();
  12.                 img.onload=function(){
  13.                         numLoaded++;
  14.                         funLoading && funLoading(numLoaded,arr.length,src,obj);
  15.                         funOnLoad && numLoaded==arr.length && funOnLoad(numError);
  16.                 };
  17.                 img.onerror=function(){
  18.                         numLoaded++;
  19.                         numError++;
  20.                         funOnError && funOnError(numLoaded,arr.length,src,obj);
  21.                 }
  22.                 img.src=src;
  23.         }

  24. }
复制代码




参数说明:

arr:可以是存放图片路径的一个数组,也可以是选取到的img的jquery对象;
funLoading:每一个单独的图片加载完成后执行的操作;
funOnLoad:全部图片都加载完成后的操作;
funOnError:单个图片加载出错时的操作。

如:

  1. var imgonload=function(errors){
  2.         /*errors:加载出错的图片数量;*/
  3.         console.log("loaded,"+errors+" images loaded error!");
  4. }

  5. var funloading=function(n,total,src,obj){
  6.         /*
  7.         n:已加载完成的数量;
  8.         total:总共需加载的图片数量;
  9.         src:当前加载完成的图片路径;
  10.         obj:当loadimg函数中传入的arr为存放图片路径的数组时,obj=src,是图片路径,
  11.                当arr为jquery对象时,obj是当前加载完成的img dom对象。
  12.        */
  13.         console.log(n+"of"+total+" pic loaded.",src);
  14.         var newimg = document.createElement("img");
  15.         newimg.src=src;
  16.         $("body").append(newimg).fadeIn();
  17. }

  18. var funloading_obj=function(n,total,src,obj){
  19.         console.log(n+"of"+total+" pic loaded.",src);
  20.         $(obj).attr("src",src);
  21.         $(obj).fadeIn(200);
  22. }

  23. var funOnError=function(n,total,src,obj){
  24.         console.log("the "+n+"st img loaded Error!");
  25. }
复制代码




调用示例:
  1. console.log("loading...");
  2. loadimg($("img"),funloading_obj,imgonload,funOnError);
  3. /*loadimg(["http://www.kevin-ying.com/20120619/9607634_212642465144_2.jpg",
  4.                  "http://www.kevin-ying.com/20120531/1670912_103610084349_2.jpg",
  5.                  "http://www.kevin-ying.com/20120616/4952071_130629530136_2.jpg",
  6.                  "http://www.kevin-ying.com/20120610/1723580_105037029000_2.jpg",
  7.                  "http://www.kevin-ying.com/20120617/2572038_125013326121_2.jpg"
  8.                 ],funloading,imgonload,funOnError);*/
复制代码





作者: kevin-ying    时间: 2016-3-27 19:22
第二个版本:

jquery.lazyloading.js的作用/加载过程/原理/设计思路:
1、刚加载页面时只加载html,不加载图片,图片的src为空,把真实的图片路径放到data-original属性中,页面加载速度变快;
2、在页面加载完成之后,js初始化,把有data-original属性的图片再加一个<div></div>在外面,再创建一个隐藏的<img />标签,并且根据原图片的大小和位置计算loading图片的位置,把loading图片显示在中间;
3、判断window的scroll事件(滚动条变化),判断图片在不在可视区域内,如果在可视区域内,那么执行第4步,否则什么也不做。
4、判断图片的src与data-original是不是相同,如果不相同(说明还没有加载),执行第5步,否则什么也不做。
5、把图片的data-original赋值给隐藏的<img />标签的src,当隐藏的图片完全加载好之后(完成后会执行它的.load()事件),再把隐藏图片的src赋值给原图片的src(原因:保证loading图片消失后目标图片立即显示,如果一开始把data-original赋值给图片的src,那么还没加载完就会显示图片,网页中图片是一截一截显示的,非常难看).


(为了保证在火狐中,图片未加载或图片路径不对,图片的位置被其他元素占用),请不要写.lazyloading的css样式,否则页面会乱。

通用的图片的html:
<div style="width: 772px; height: 449px;">
   <img class="lazyloading" src="" data-original="/ListPicThumbnail/list90.jpg" height="772" width="449">
</div>
或者l:

<div style="width: 772px; height: 449px;">
   <a href="#" target="_blank"> <img class="lazyloading" src="" data-original="/ListPicThumbnail/list90.jpg" height="772" width="449"> </a>
</div>

不断修改完善中……

最后更新:2013-12-17 16:00:00
加载等的图片:




[JavaScript] 纯文本查看 复制代码
/*! 
* jquery.lazyoading.js
*自定义的页面图片延迟加载插件,比网上的jquery.lazyload简单,也更适合自己的网站
*使用方法:
把img 的class加上 lazyloading,data-original 放图片的真实路径
然后先引用jquery,再引用jquery.lazyoading.js,再调用:$("img.lazyloading").lazyloading({loadfirst:true});
* by pukuimin
* 2013-11-01
*2013-11-08 解决了图片没有指定高度的问题
*2013-11-14 解决了没有指定高度加载图片之后有间隔的问题
*2013-12-17 加入了<span>图片显示时的 animate过渡效果</span>,把alt赋值给title
*/  
/// <reference path="jquery-1.8.2.min.js" />  
(function ($) {  
    $.fn.lazyloading = function (options) {  
        var defaults = {  
            preyimg: "/Content/images/Imgpreview/grey.gif",  
            picpath: "data-original",  
            container: $(window),  
            loadfirst: false, //进入页面后是否加载当前页面的图片  
            defaultHeightID: "lazyloadingHeight"//页面上默认高度的input标签id  
            //imgPaddingID: "lazyloadingPadding"//img的padding值  
        };  
        var params = $.extend({}, defaults, options || {});  
        params.cache = [];  
        $(this).each(function () {  
            var node = this.nodeName.toLowerCase(), url = $(this).attr(params["picpath"]), preyimg = params["preyimg"];  
            var defaultheight = $("#" + params["defaultHeightID"]).val(); //, padding = $("#" + params["imgPaddingID"]).val(); //  
            //重组  
            var data = {  
                obj: $(this),  
                tag: node,  
                url: url,  
                preyimg: preyimg,  
                defaultheight: defaultheight  
            };  
            params.cache.push(data);  
        });  
  
        var init = function () {  
            $.each(params.cache, function (i, data) {  
                var thisImg = data.obj, tag = data.tag, url = data.url, preyimg = data.preyimg;  
                if (typeof (url) != "undefined")// 判断是否需要延迟加载  
                {  
                    var parent1 = thisImg.parent(); //a  
                    var Inner = null; //  
                    if (parent1.is("a") == true) {//img wrap by a  
                        Inner = parent1;  
                    }  
                    else {  
                        Inner = thisImg;  
                    }  
                    var width = thisImg.attr("width") || thisImg.css("width");  
                    var height = data.defaultheight || thisImg.css("height");  
                    //if (i == 0) alert(data.defaultheight);  
                    var attrheight = thisImg.attr("height");  
                    if (attrheight != null) height = attrheight;  
                    if (width != null && width.indexOf("px") > -1) width.replace("px", "");  
                    if (height != null && height.indexOf("px") > -1) height.replace("px", "");  
                    var divstr = "<div class='.loading' style='text-align: left;position:relative;float:left;width:" + width + "px;";  
                    var HasHeight = true; //图片是否指定了高度  
                    divstr = divstr + "height:" + height + "px;";  
                    if (attrheight == null || attrheight == "") {  
                        HasHeight = false;  
                    }  
  
                    thisImg.css("position", "relative");  
  
                    divstr = divstr + "' ></div>"  
                    //修正外层div:text-align的影响  
                    Inner.wrap(divstr);  
                    //修正img外面不是a标签时parent()已经改变的问题  
                    parent1 = thisImg.parent();  
                    if (HasHeight == true) { parent1.attr("lazyloading_hasheight", "1"); } //是否指定了高度  
                    else { { parent1.attr("lazyloading_hasheight", "0"); } }  
                    parent1.append("<img class='loadhiddenimg' width='0' height='0' style='display:none;' src='' />");  
                    thisImg.attr("src", preyimg);  
                    thisImg.removeAttr("width").removeAttr("height");  
                    thisImg.attr("width1", width).attr("height1", attrheight);  
  
                    ////thisImg.attr("width", "50px").attr("height", "50px"); //loading图大小  
                    //thisImg.css("margin", "0 auto");  
                    thisImg.css("margin", ((height / 2) - 25) + "px auto auto " + ((width / 2) - 25) + "px");  
                    $(".lazyloading").css("display", "table"); //.css("position", "relative");  
                }  
            });  
        }  
        //动态显示数据  
        var loading1 = function () { };  
        var loading = function () {  
            //窗口的高度+看不见的顶部的高度=屏幕低部距离最顶部的高度  
            var thisButtomTop = parseInt($(window).height()) + parseInt($(window).scrollTop());  
            var thisTop = parseInt($(window).scrollTop()); //屏幕顶部距离最顶部的高度  
  
            $.each(params.cache, function (i, data) {  
                var thisImg = data.obj, tag = data.tag, url = data.url, post, posb;  
  
                if (thisImg) {//对象不为空  
                    if (typeof (url) != "undefined") {// 判断是否需要延迟加载  
                        var PictureTop = parseInt(thisImg.offset().top);  
                        //如果处理可见范围内,并且原图地址data-original不等于src,则加载图片  
                        if (PictureTop >= thisTop && PictureTop <= thisButtomTop && thisImg.attr("data-original") != thisImg.attr("src")) {  
                            var hiddenImg = thisImg.siblings("img.loadhiddenimg");  
  
                            hiddenImg.load(function () { //隐藏图片加载完之后的回调函数  
                                var width = thisImg.attr("width1");  
                                var height = thisImg.attr("height1");  
                                thisImg.attr("width", width).attr("height", height).removeAttr("width1").removeAttr("height1");  
                                thisImg.css("margin", "0 auto");  
                                if (thisImg.parent().attr("lazyloading_hasheight") == "0") {//没有指定高度时,加载图片后去掉div高度自适应  
                                    if (thisImg.parent().is("a") == true) {  
                                        thisImg.parent().parent().css("height", "");  
                                    }  
                                    else {  
                                        thisImg.parent().css("height", "");  
                                    }  
                                }  
                                thisImg.load(function () {  
                                    if (thisImg.parent().is("a") == true) {  
                                        thisImg.parent().parent().css("height", thisImg.height());  
                                    }  
                                    else {  
                                        thisImg.parent().css("height", thisImg.height());  
                                    }  
                                });  
                                thisImg.css('opacity', '0.2');  
                                thisImg.attr("src", hiddenImg.attr("src"));  
                                thisImg.animate({ opacity: 1.0 });  
                                if (thisImg.attr("alt") != "") {  
                                    thisImg.attr("title", thisImg.attr("alt"));  
                                    thisImg.attr("alt", "");  
                                }  
                            }).error(function () {  
                                thisImg.error(function () {  
                                    thisImg.css("margin", "0 auto auto 0");  
                                    if (thisImg.parent().attr("lazyloading_hasheight") == "0") {//没有指定高度时,加载图片后去掉div高度自适应  
                                        if (thisImg.parent().is("a") == true) {  
                                            thisImg.parent().parent().css("height", "");  
                                        }  
                                        else {  
                                            thisImg.parent().css("height", "");  
                                        }  
                                    }  
                                });  
                                thisImg.attr("src", hiddenImg.attr("src")); //alert("error");  
                                if (thisImg.attr("alt") != "") {  
                                    thisImg.attr("title", thisImg.attr("alt"));  
                                    thisImg.attr("alt", "");  
                                }  
                            });  
                            hiddenImg.attr("src", url);  
                        }  
                    }  
                }  
            });  
        };  
        //初始化  
        init();  
        //事件触发  
        //加载完毕即执行  
        if (params["loadfirst"] == true) loading();  
        //滚动执行  
        params.container.bind("scroll", loading).bind("resize", loading);  
    };  
})(jQuery);



用法示例:
[HTML] 纯文本查看 复制代码
<div style="width: 190px; height: 237px; float: left;"><a href="http://maga.kinpan.com/Magazine/MagazineEachperiod/sdlp?id=201311011146457968750c36ca60628">
  <img  alt="商业街区" src="" data-original="http://account.kinpan.com/Upload/Magazine/MagazineBookImage/201311011141232812500a4cbf15f0f.jpg" width="190" height="237" class="lazyloading" /></a>
</div>

<script type="text/javascript">
$(function () {
    $("img.lazyloading").lazyloading({ loadfirst: true });
})
</script>







欢迎光临 源于生活 (http://bbs.vingoo.info/) Powered by Discuz! X3.1