为什么需要页面图片惰性延迟加载?
当页面内图片达到一定的数量,页面的加载速度就越来越差.
我们并不需要把所有图片一次性加载完,而且,用户也不会一次性把所有图片看完.
所以,我们需要做的就是按需加载,只显示用户需要看的图片
图片惰性延迟加载好处
1. 按需加载图片,加快加载页面速度
2. 减少对服务器的请求数
3. 减少初始页面加载页面大小
图片惰性延迟加载坏处
1. SEO,因为图片都被替换成假的图片,所以会影响图片的收录,所以这功能不建议在详情页使用
未加图片惰性加载功能:
图片惰性延迟性能对比
已加图片惰性加载功能:
(FF firebug测试数据)由图片可以看出,请求数,页面大小,加载时间,都快了将近一倍~!!!
图片惰性延迟加载程序思路
1. 把需要延迟加载的图片加一个标识
2. 获取这些被标识的图片离页面顶部的高度
3. 添加浏览器滚动条事件,当滚动条滑动时,判断有哪些图片在这个可视区域内
4. 把可视区域内的图片替换真实的图片
5. 去除已替换成功的图片的标识
6. 若全部图片已替换,移去滚动条事件
图片惰性延迟加载关键代码
1. 获取图片距离页面顶部的高度
1 get_pos:function(elem){ 2 3 4 if(!elem) return false; 5 6 7 var left = elem.offsetLeft, 8 9 10 top = elem.offsetTop, 11 12 13 current = elem; 14 15 16 if(!top){ 17 18 19 while(current!=document && current!=null && !current.offsetTop){ 20 21 22 current = current.parentNode ; 23 24 25 } 26 27 28 }else{ 29 30 31 current = elem.offsetParent || elem.parentNode ; 32 33 34 } 35 while(current!=document && current!=null){ 36 37 38 left += current.offsetLeft; 39 40 41 top += current.offsetTop; 42 43 44 current = current.offsetParent || current.parentNode ; 45 46 47 } 48 49 50 return {"left": left, "top": top}; 51 52 53 }
我们利用offsetTop和offsetParent获取当前元素离页面顶部高度
*这里需要注意,在IE浏览器,隐藏的元素的offsetTop值会是0
2.获取页面可视区域底部到页面顶部的距离
1 var winHeight=win.innerHeight || document.documentElement.clientHeight; 2 3 4 var scrTop=document.body.scrollTop || document.documentElement.scrollTop;
*这里需要注意IE和webkit获取滚动条滚动距离和页面可视区域高度的方式都不同
3.判断图片是否在可视区域内
1 if(iSrc){ 2 3 4 if(winHeight+scrTop+This.img.lazy>=node.xLazyPos.top && scrTop?This.img.lazy<=node.xLazyPos.top){ 5 6 7 var img=new Image(); 8 9 10 img.onload = function(){ 11 12 13 14 node.setAttribute(‘src‘,iSrc); 15 16 17 }; 18 19 20 img.src=iSrc; 21 22 23 }
图片惰性延迟加载进阶效果
1. 当浏览器可视区域大小变化的时候,图片距离页面顶部的距离将会改变,这时我们应该重新获取数据
2. 图片替换时可加一个渐变效果,这样会不会感觉那么生硬
3. 滚动条左右滑动显示图片
4. ect
插件源码:
/** * 名称:xmanLazyLoad * 功能:网页图片惰性加载,兼容各浏览器 * 用法: 使用方法: 1.加载JS <script type="text/javascript" src="lazy_load.js" ></script> 2.设置IMG属性 <img src="http://placehold.it/90x90" class="xLazyClass" xLazyImg="http://image.game.uc.cn/2014/2/17/9631225.jpg" alt="仙剑奇缘"/> API 1.设置class 需要惰性加载的图片class="xLazyClass" 2.设置图片真实路径 xLazyImg="http://image.game.uc.cn/2014/2/17/9631225.jpg" 3.设置图片假路径 src="http://placehold.it/90x90" * @author luozx * @Email luozx@ucweb.com * @version 1.0.0 * @dependencies none */ (function(a,b){var c={getByClass:function(a,b){for(var c=a.getElementsByTagName("*"),d=[],e=new RegExp("\\b"+b+"\\b","i"),f=0;f<c.length;f++)e.test(c[f].className)&&d.push(c[f]);return d},get_pos:function(a){if(!a)return!1;var b=a.offsetLeft,c=a.offsetTop,d=a;if(c)d=a.offsetParent||a.parentNode;else for(;d!=document&&null!=d&&!d.offsetTop;)d=d.parentNode;for(;d!=document&&null!=d;)b+=d.offsetLeft,c+=d.offsetTop,d=d.offsetParent||d.parentNode;return{left:b,top:c}},removeClass:function(a,b){if(!a||!a.className)return!1;for(var c=a.className.split(" "),d=!1,e=0;e<c.length;e++)if(c[e]===b){c.splice(e,1),d=!0;break}if(d){if(a.className="",c.length<1)return d;if(1==c.length)a.className=c[0];else if(c.length>1)for(var e=0;e<c.length;e++)a.className+=e==c.length-1?c[e]:c[e]+" "}return d},addEvent:function(a,b,c){if(a){if(a.addEventListener)return a.addEventListener(b,c,!1);if(a.attachEvent)return a.attachEvent("on"+b,c);a["on"+b]=c}},removeEvent:function(a,b,c){if(a){if(a.removeEventListener)return a.removeEventListener(b,c,!1);if(a.detachEvent)return a.detachEvent("on"+b,c);a["on"+b]=null}},startMove:function(a,b,d){clearInterval(a.timer),a.timer=setInterval(function(){var e=!0;for(var f in b){var g=0;g=parseInt("opacity"==f?100*parseFloat(c.getStyle(a,f)):c.getStyle(a,f));var h=(b[f]-g)/8;h=h>0?Math.ceil(h):Math.floor(h),g!=b[f]&&(e=!1),"opacity"==f?(a.style.filter="alpha(opacity:"+(g+h)+")",a.style.opacity=(g+h)/100):a.style[f]=g+h+"px"}e&&(clearInterval(a.timer),d&&d())},30)},getStyle:function(a,b){return a.currentStyle?a.currentStyle[b]:getComputedStyle(a,!1)[b]}},d={init:function(){this.parm(),this.getImg(),this.getPos(),this.bindEvent(),this.lazyShow()},parm:function(){var a=b.getElementById("xManLazyLoad");this.img={},this.img.onerrorImgUrl="",this.img.srcStore=a?a.getAttribute("xdata-attr"):"xLazyImg",this.img.className=a?a.getAttribute("xdata-class"):"xLazyClass",this.img.lazy=a?parseInt(a.getAttribute("xdata-lazy")):20},getImg:function(){this.img.node=c.getByClass(b.getElementsByTagName("body")[0],this.img.className),this.img.length=this.img.node.length},getPos:function(){for(var a=d,b=0;b<a.img.node.length;b++)a.img.node[b].xLazyPos=c.get_pos(a.img.node[b])},bindEvent:function(){this.img.node.length>0&&(c.addEvent(a,"scroll",this.lazyShow),c.addEvent(a,"resize",this.getPos))},lazyShow:function(){var e=d,f=a.innerHeight||document.documentElement.clientHeight,g=document.body.scrollTop||document.documentElement.scrollTop;if(e.img.length>0)for(var h=0;h<e.img.node.length;h++)~function(a){var b=e.img.node[a],d=b.getAttribute(e.img.srcStore);if(d&&f+g+e.img.lazy>=b.xLazyPos.top&&g-e.img.lazy<=b.xLazyPos.top){var h=new Image;h.onload=function(){b.style.filter="alpha(opacity:0)",b.style.opacity=0,b.setAttribute("src",d),e.img.length--,c.startMove(b,{opacity:100}),c.removeClass(b,e.img.className),b.removeAttribute(e.img.srcStore)},h.src=d}}(h);else e.img.node=c.getByClass(b.getElementsByTagName("body")[0],e.img.className),e.img.length=e.img.node.length,e.img.length<=0&&c.removeEvent(a,"scroll",e.lazyShow),c.removeEvent(a,"resize",e.getPos)}};d.init()}(window,document));