网页在加载一张大图片时,往往要加载很久;
而且,在加载过程中,无法很好地控制图片的样式,容易造成错位等显示错误;
如果能够在加载大图时,先使用一张较小的loading图片占位,然后后台加载大图片,当大图片加载完成后,自动替换占位图,
这样能提供更好的用户体验;
由于,我在开发一个图片查看器时,遇到这样的需求,所以我写了个angular服务,来解决这个问题,效果还不错;
虽然是angular服务,当是把里面核心代码抽出来也可以单独使用;
来分享下源代码:
一:
var imgloader = new Object(); imgloader.placeholder = new Image();
imgloader是主要的对象
placeholder 用于存储占位图片
二:
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(){}; // } // };