写了个lazyload,其实以前也写过一个版本,只是感觉太耗资源了,这次重写了一个,优化了一下。目前来说感觉还行吧,等以水平提高了,再继续优化吧。(另:感谢檬檬桑给我提供的domReady函数,相当在天朝这么神奇的国度,不会出现网速极快的情况吧,所以这个函数应该还可以。呵呵,当然你也可以用自己的domReay.)
JS:
function lazyload(){this.init.apply(this,arguments)}; lazyload.prototype = { init:function(container,img,defaultImg){ /* 参数说明: container :外层框,也可以是window img :需要延时加载的图片的集合 defaultImg :默认替换图片 */ var _this = this; var doc = document, isWindow = container == window || container == doc || !container.tagName || (/^(?:body|html)$/i).test(container.tagName); if(isWindow) container = doc.compatMode == 'CSS1Compat' ? doc.documentElement : doc.body; this.container = container; this.img = img; this.items_property = []; defaultImg = defaultImg || 'blank.gif'; //domReady的时候this.items_property里存放每个图片的位置,高宽。 this.domReady(function(){ var i=0,len=_this.img.length; for(;i<len;i++){ _this.items_property[i] = { t:_this.img[i].offsetTop, h:_this.img[i].offsetHeight, l:_this.img[i].offsetLeft, w:_this.img[i].offsetWidth } _this.img[i].setAttribute('original',_this.img[i].src); _this.img[i].src = defaultImg; } }); //用于存放已加载图片的个数,当this.counter等于图片的个数的时候,说明所有的图片都已经加载完毕。 this.counter = 0; //记录外框的属性 this.container_property = { t:this.container.offsetTop, l:this.container.offsetLeft, h:this.container.clientHeight, w:this.container.clientWidth } this.addEvent(this.container,'scroll',function(){_this.scroll()}); //如果是window isWindow && this.addEvent(window,'scroll',function(){_this.scroll()}); isWindow && this.addEvent(window,'resize',function(){_this.scroll()}); /* 这个地主用到了 setTimeout其实我自己也很奇怪, 因为不加setTimeout,上面的this.items_property里没有内容, 就是说上面的domReady里的for还没有执行。原因我也不知道。 */ setTimeout(function(){_this.scroll();},100) }, domReady:function(fn){ var isIE =!-[1,] if (!isIE){ document.addEventListener("DOMContentLoaded", fn, false); }else{ window.setTimeout(fn,0); } }, addEvent:function(el,type,fn){ if(el.addEventListener){ el.addEventListener(type,fn,false); }else if(el.attachEvent){ el.attachEvent('on'+type,function(){ fn.call(el,window.event); }) }else{ el['on'+type] = fn; } }, loadImg:function(url,callback){//加载图片 var img = new Image(),ie = !-[1,]; img.src = url; if(ie){ img.onreadystatechange = function(){ if(img.readyState == 'complete') callback(img); } }else{ img.onload = function(){ if(img.complete == true) callback(img); } } }, hasLoaded:function(img,property){//判断图片是否已经加载 return img.src == img.getAttribute(property); }, scroll:function(){ //当所有的图片都已经加载完,直接返回 if(this.counter == this.img.length) return; var _this = this; /* *这里用到setTimeout的用处有两个 *一:尽量减少onscroll时的执行次数,从而减少资源消耗 *二:如果拖动的太快,比如快速将滚动条从最下面拖到最下面,那么中间的那部份是不会被加载的,这很符合情理。因为这个时间 里中间那部份并不在可视化范围内。理论上是不应该被加载的。 */ setTimeout(function(){ var container_pos = { st : _this.container.scrollTop, sl : _this.container.scrollLeft }; for(var i=0,len=_this.img.length; i<len; i++){ //当可视化范围内的图片是已经被加载过,那么直接跳到下一次循环 if(_this.hasLoaded(_this.img[i],'original')) continue; _this.t = _this.items_property[i].t - _this.container_property.t - _this.container_property.h; _this.b = _this.items_property[i].t + _this.items_property[i].h - _this.container_property.t; _this.l = _this.items_property[i].l - _this.container_property.l - _this.container_property.w; _this.r = _this.items_property[i].l + _this.items_property[i].w - _this.container_property.l; //判断图片是否在可视化范围内,即可以上下,也可以左右。 if(_this.t < container_pos.st && container_pos.st < _this.b && _this.l < container_pos.sl && container_pos.sl < _this.r){ (function(i){ //如果图片在可视化范围内,那么加截该图片,并将记数器累加一次 _this.loadImg(_this.img[i].getAttribute('original'),function(img){ _this.img[i].src = img.src; _this.counter++; }) })(i); } } },200); } }
HTML:(外框为普通层)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>无标题文档</title> <style type="text/css"> #img_box { width:620px; height:500px; overflow:auto; margin:100px auto; border:1px solid #ddd;} #img_box ul { list-style:none; padding:0; margin:0;} #img_box ul li { margin-bottom:10px;} #img_box ul li img { display:block;} </style> <script type="text/javascript" src="lazyload_sky.js"></script> </head> <body> <div id="img_box"> <ul> <li><img src="http://img.article.pchome.net/new/w600/00/36/63/99//pic_lib/wm/Lengse05.jpg" width="600" height="375" /></li> <li><img src="http://img.article.pchome.net/new/w600/00/36/63/99//pic_lib/wm/Lengse07.jpg" width="600" height="375" /></li> <li><img src="http://img.article.pchome.net/new/w600/00/36/63/99//pic_lib/wm/Lengse08.jpg" width="600" height="375" /></li> <li><img src="http://img.article.pchome.net/new/w600/00/36/63/99//pic_lib/wm/Lengse10.jpg" width="600" height="375" /></li> <li><img src="http://img.article.pchome.net/new/w600/00/36/63/99//pic_lib/wm/Lengse11.jpg" width="600" height="375" /></li> <li><img src="http://img.article.pchome.net/new/w600/00/36/63/99//pic_lib/wm/Lengse12.jpg" width="600" height="375" /></li> <li><img src="http://img.article.pchome.net/new/w600/00/36/63/99//pic_lib/wm/Lengse13.jpg" width="600" height="375" /></li> <li><img src="http://img.article.pchome.net/new/w600/00/36/63/99//pic_lib/wm/Lengse16.jpg" width="600" height="375" /></li> <li><img src="http://img.article.pchome.net/new/w600/00/36/63/99//pic_lib/wm/Lengse17.jpg" width="600" height="375" /></li> <li><img src="http://img.article.pchome.net/new/w600/00/36/63/99//pic_lib/wm/Lengse19.jpg" width="600" height="375" /></li> </ul> </div> <script type="text/javascript"> var box = document.getElementById('img_box'),img = box.getElementsByTagName('img'); new lazyload(box,img); </script> </body> </html>
HTML:(外框为window)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>无标题文档</title> <style type="text/css"> #img_box {width:600px; /* height:500px; */margin:0 auto; border:1px solid #ddd;} #img_box ul { list-style:none; padding:0; margin:0;} #img_box ul li { margin-bottom:10px;} #img_box ul li img { display:block;} </style> <script type="text/javascript" src="lazyload_sky.js"></script> </head> <body> <div id="img_box"> <ul> <li><img src="http://img.article.pchome.net/new/w600/00/36/63/99//pic_lib/wm/Lengse05.jpg" width="600" height="375" /></li> <li><img src="http://img.article.pchome.net/new/w600/00/36/63/99//pic_lib/wm/Lengse07.jpg" width="600" height="375" /></li> <li><img src="http://img.article.pchome.net/new/w600/00/36/63/99//pic_lib/wm/Lengse08.jpg" width="600" height="375" /></li> <li><img src="http://img.article.pchome.net/new/w600/00/36/63/99//pic_lib/wm/Lengse10.jpg" width="600" height="375" /></li> <li><img src="http://img.article.pchome.net/new/w600/00/36/63/99//pic_lib/wm/Lengse11.jpg" width="600" height="375" /></li> <li><img src="http://img.article.pchome.net/new/w600/00/36/63/99//pic_lib/wm/Lengse12.jpg" width="600" height="375" /></li> <li><img src="http://img.article.pchome.net/new/w600/00/36/63/99//pic_lib/wm/Lengse13.jpg" width="600" height="375" /></li> <li><img src="http://img.article.pchome.net/new/w600/00/36/63/99//pic_lib/wm/Lengse16.jpg" width="600" height="375" /></li> <li><img src="http://img.article.pchome.net/new/w600/00/36/63/99//pic_lib/wm/Lengse17.jpg" width="600" height="375" /></li> <li><img src="http://img.article.pchome.net/new/w600/00/36/63/99//pic_lib/wm/Lengse19.jpg" width="600" height="375" /></li> </ul> </div> <script type="text/javascript"> var img = document.getElementById('img_box').getElementsByTagName('img'); new lazyload(document,img); </script> </body> </html>