最高半折刷qq各种业务和钻(家里人自己开的,尽管放心,大家多捧捧场)

sking7

导航

JS延迟加载机制函数(Lazyload)

原文:http://www.qiqiboy.com/2010/08/27/js-delayed-loading-mechanism-function-lazyload.html

最近应该大家都发现了,我的博客很多模块都使用了延迟加载技术。这个延迟加载(lazyload)我第一次听说其实还是不久前,那是在别人博客看到 介绍的一个基于jQuery的图片延迟加载插件。我对这个很感兴趣,其实很多网站也都应用了这个技术,尤其是大型网站,可以有效地减少服务器压力。

我原先觉得这个技术挺神秘的,实现起来应该比较困难,并且在网上也并没有找到相关的文章或者介绍。但是当我真正决定要去这样做时,却发现其实这个真的挺简单的,原理也容易理解。

lazyload,简单地说,就是在浏览器滚动到某个位置时再出发相关函数,实现页面元素的加载或者某些动作的执行。浏览器的滚动位置检测,可以通 过一个定时器来循环检测,通过比较某一时刻页面目标节点位置和浏览器滚动条高度来判断需不要要执行函数。我将这个方法写成了一个类,我自己博客即是使用我 的这个方法。

(下面代码纯属自己的小试手,如果有不完善地方可以指出)

   1: function Lazyload(func, obj) {//obj目标节点对象, func要触发的函数
   2:     this.func = func;
   3:     this.obj = obj;
   4:     this.it = setInterval(function() {//2s检查一次
   5:         this.checkScroll();
   6:     }.bind(this), 2000);//bind为setInterval绑定lazyload对象,否则this会指向window对象
   7: }
   8:  
   9: Function.prototype.bind = function(obj) {//对象绑定
  10:     var __method = this;
  11:     return function() { 
  12:         return __method.apply(obj, arguments); 
  13:     };
  14: }
  15:  
  16: Lazyload.prototype.checkScroll = function() {
  17:     var scrollY = document.body.scrollTop || document.documentElement.scrollTop || window.pageYOffset || 0,//页面滚动条高度
  18:         seeY = window.innerHeight||document.documentElement.clientHeight,//浏览器可视区域高度
  19:         func = this.func;
  20:     if (Math.abs(this.getY() - scrollY) < seeY) {//当目标节点进入可视区域,即页面滚动条高度减去节点距页面顶部距离小于浏览器可视高度
  21:         clearInterval(this.it);//清除定时器
  22:         return func();
  23:     }
  24: }
  25:  
  26: Lazyload.prototype.getY=function(){//目标节点距页面顶部高度
  27:     var obj=this.obj;
  28:     tp = obj.offsetTop;
  29:     if (obj.offsetParent) while (obj = obj.offsetParent) tp += obj.offsetTop;
  30:     return tp;
  31: }

关于代码的一些解释都在注释里了。如何使用呢?

 

使用这个方法要通过new来新建类对象的方法。参数func即是要触发的函数,obj即是页面上某个节点对象,即当此obj节点进入可视区域时(浏 览器滚动到此处)即触发func函数。比如,你要实现当浏览器滚动到页面上id为“test”的节点(b)时触发弹出窗口alert(‘yes’),可以 这么做

   1: function a(){alert('yes');}//要出发的函数
   2: var b=document.getElementById('tests');//获取页面节点
   3: new Lazyload(a,b);//使用new关键字建立对象执行

以上就是我自己的lazyload的全部代码与实现方式了。当然,我相信它还有改进之处。

补充一些其他的东西:

我的代码中定时检测的时间设定是2s,也就是说每两秒去比较一次。如果你浏览器拖动太快,目标节点被很快的一闪而过,很可能此时就刚好没有执行 checkScroll函数,所以也就不会触发动作了。你可以将时间改为更小的值(在第6行),如500ms,可以避免大多数的快速拖动造成的问题。当 然,我觉得其实没必要,如果某人很快的拖动滚动条,说明他要浏览的东西在页面底部,那么其实是没必要加载他快速拖动过的节点的,所以2s我觉得是一个很合 理的值。

另外一个问题是我的代码是只触发出现在可视区域中的节点动作,如果你想要实现在当前浏览的页面以上部分的节点全部要加载,那么可以将代码的第20行去掉Math.abs即可。如果要实现在滚动到距目标节点一定高度时就开始触发函数,那么可将20行的seeY改为seeY+200(200即为设定的距离高度)。

关于lazyload的一个具体的实现,就还拿图片的延迟加载来说吧。你可以将图片的地址都改成一个默认的小图片(这个可以在后台用php直接修改 输出,也可以用js实现),将正真的图片地址存到图片的alt属性中(也可以指定一个自定义的属性),然后对每个图片绑定new lazyload,要触发的动作函数就是将alt中的值赋给src即可。这样,就实现了图片的lazyload(你就可以消灭jQuery,消灭 jQuery的lazyload插件了,也就消灭了那100来K的JS文件)。如果再结合ajax技术,那么也就可以实现如我博客一样的模块延迟加载了。

posted on 2012-01-15 09:53  G.N&K  阅读(2159)  评论(0编辑  收藏  举报