javascript图片加载---加载大图的一个解决方案

网页在加载一张大图片时,每每要加载好久;javascript

并且,在加载过程当中,没法很好地控制图片的样式,容易形成错位等显示错误;css

若是可以在加载大图时,先使用一张较小的loading图片占位,而后后台加载大图片,当大图片加载完成后,自动替换占位图,html

这样能提供更好的用户体验;java

因为,我在开发一个图片查看器时,遇到这样的需求,因此我写了个angular服务,来解决这个问题,效果还不错;函数

虽然是angular服务,当是把里面核心代码抽出来也能够单独使用;布局

来分享下源代码:测试

一:spa

var imgloader = new Object();
        imgloader.placeholder = new Image();

imgloader是主要的对象code

placeholder 用于存储占位图片htm

二:

imgloader.init = function(placeholderPath,width,height){
            imgloader.placeholder.src = placeholderPath;
            imgloader.placeholder.width = width;
            imgloader.placeholder.height = height;
        }

init是imgloader的初始化方法,主要指定了占位图片的文件,已经它的宽高;

设置宽高的目的是为了在占位图还未加载完成时也能进行布局

三:

imgloader.load = function(imgElem,imgSrc,callback){
        //清除以前的onload函数
        if(imgElem.lastload){
            imgElem.lastload.onload = function(){};
        }
        loadok = false;
        var testImg = new Image();
            testImg.src = imgSrc;
        if(testImg.complete == true){
           imgElem.src = testImg.src;
           imgElem.width = testImg.naturalWidth;
           if(imgElem.hasAttribute("height")){
               imgElem.removeAttribute("height");
           }
        }else{
           imgElem.src = imgloader.placeholder.src;
           imgElem.width = imgloader.placeholder.width;
           imgElem.height = imgloader.placeholder.height;
           //只读属性
//               imgElem.naturalWidth = imgElem.width;
//               imgElem.naturalHeight = imgElem.height;
//               console.log(imgElem.naturalWidth+"|"+imgElem.naturalHeight);
           //绑定onload函数
           testImg.onload = function(){
               imgElem.src = testImg.src;
               imgElem.width = testImg.naturalWidth;
               if(imgElem.hasAttribute("height")){
                   imgElem.removeAttribute("height");
               }
                if(callback){
                    callback();
                }
           };
            
           imgElem.lastload = testImg;
//           imgloader.loadingArray.push(imgElem);
        }
    };


1.一开始,若是对同一个图片元素设置了多个load,则只有最后一个生效,以前的都会被替换;

2.使用大图的src设置一个img作测试,若是这张图片已经加载过了,那就直接设置上这张大图;

3.注意这里我还原了被设置元素的宽高,为的是避免被设置元素的宽高收到占位符宽高的影响;

4.小技巧:设置完width后,把height属性移除的话,height会自适应width

5.若是testImg(大图)未加载完成,则先用占位图代替,注意被设置图片的宽高被修改为与占位图相同的大小;

6.为testImg(大图)绑定onload函数,当大图加载完成后,被设置元素的src替换成大图的src,并恢复大图的框高;

7.有设置回调的,能够在回调中再作些事情;

8.设置这个imgElem已经绑定一个大图(再次绑定的话,这个会被消去)

9.小技巧:naturalWidth与naturalHeight是只读属性

四:

一个例子:

<html>
    <head>
        <meta charset="utf-8">
		<meta name="viewport" content="width=device-width,initial-scale=1.0">
        <style>
            img{
                max-width: 100%;   
            }
            #img1{
                width:  200px;
                height: 200px;
            }
            #img2{
                width: 200px;
                height: 200px;
            }
        </style>
    </head>
    <body>
        <img id="img1">
        <img id="img2">
        <script src="mikuImgLoader3.0.js"></script>
        <script>
            imgloader.init("dokidoki.gif",200,200);
            imgloader.load(img1,"001.jpg");
            imgloader.load(img2,"002.jpg");
        </script>
    </body>
</html>

例子中能够看出:还能够用css控制被设置图片的大小

五:

完整代码:

//miku图片加载器3.0
var imgloader = new Object();
    imgloader.placeholder = new Image();
//    imgloader.loadingArray = new Array();

    imgloader.init = function(placeholderPath,width,height){
        imgloader.placeholder.src = placeholderPath;
        imgloader.placeholder.width = width;
        imgloader.placeholder.height = height;
    };
    imgloader.load = function(imgElem,imgSrc,callback){
        //清除以前的onload函数
        if(imgElem.lastload){
            imgElem.lastload.onload = function(){};
        }
        var testImg = new Image();
            testImg.src = imgSrc;
        if(testImg.complete == true){
           imgElem.src = testImg.src;
           imgElem.width = testImg.naturalWidth;
           if(imgElem.hasAttribute("height")){
               imgElem.removeAttribute("height");
           }
        }else{
           imgElem.src = imgloader.placeholder.src;
           imgElem.width = imgloader.placeholder.width;
           imgElem.height = imgloader.placeholder.height;
           //只读属性
//               imgElem.naturalWidth = imgElem.width;
//               imgElem.naturalHeight = imgElem.height;
//               console.log(imgElem.naturalWidth+"|"+imgElem.naturalHeight);
           //绑定onload函数
           testImg.onload = function(){
               imgElem.src = testImg.src;
               imgElem.width = testImg.naturalWidth;
               if(imgElem.hasAttribute("height")){
                   imgElem.removeAttribute("height");
               }
                if(callback){
                    callback();
                }
           };
            
           imgElem.lastload = testImg;
//           imgloader.loadingArray.push(imgElem);
        }
    };
//    //清除加载队列的全部onload函数
//    function clearOnload(loadingArray){
//        for(var i=0;i<loadingArray.length;i++){
//            var loading = loadingArray[i];
//            loading.onload = function(){};
//        }
//    };