javascript控件之实现滚动条触底加载数据

一、背景:
     当用户信息较多,页面在展示数据时为减少加载时间,传统方法是采用分页显示,用户查看上一页数据或下一页数据时,需要来回切换,影响体验。现各大微博网站使用新方法弥补分页的不足:如数据过多,页面无法全部展示则先展示部分数据并显示滚动条,用户滑动滚动条触底时再加载部分新数据,而页面之前的数据仍将保留。
二、功能:
    模拟实现各大微博网站所采用的当滚动条触底加载数据的技术。
三、说明:
  1、 v2.0版本
          window.ScrollLoadData(id,callBack)
          第一个参数必须:id为需要触发scroll事件的元素id。当传入的参数是window时,则scroll事件绑定在window上
          第二个参数可选:scroll事件触发的回调函数,需用户自行实现。
  2、v1.1版本
          window.scrollLoadData(id/window,callBack);
          第一个参数必须:id为需要触发scroll事件的元素id。当传入的参数是window时,则scroll事件绑定在window上
          第二个参数可选:scroll事件触发的回调函数,需用户自行实现。
四、使用:
  1、v2.0版:约定俗成:凡是带有_前缀的方法/属性无特殊说明都为私有的,不能提供给外部调用.未带有_前缀的方法/属性供外部调用.
        (1)将scroll事件绑定到id为test的元素上
      var sld = new window.ScrollLoadData('test',function(){alert('execute')});
      sld.scrollLoadData();
        (2)将scroll事件绑定到window上
        var sld = new window.ScrollLoadData(window,function(){alert('execute')});
        sld.scrollLoadData();
        (3)调用setIsScrollLoaded设置私有属性_isScrollLoaded的值
        在向后台发送加载数据请求之前需调用setIsScrollLoaded方法将_isScrollLoaded设置为false;
        当后台响应请求之后需调用setIsScrollLoaded方法将_isScrollLoaded设置为true,无论这个响应请求是成功还是失败的;
  2、v1.1版:
        (1)将scroll事件绑定到id为test的元素上
      window.scrollLoadData('test',function(){alert('execute')});
        (2)将scroll事件绑定到window上 
      window.scrollLoadData(window,function(){alert('execute')});
        (3)调用setIsScrollLoaded设置私有属性_isScrollLoaded
        在向后台发送加载数据请求之前需调用setIsScrollLoaded方法将_isScrollLoaded设置为false;
        当后台响应请求之后需调用setIsScrollLoaded方法将_isScrollLoaded设置为true,无论这个响应请求是成功还是失败的; 
五、版本说明:
     版本V2.0使用面向对象封装成ScrollLoadData类,实现了多个元素分别绑定.每绑定一个元素时都需重新new一个ScrollLoadData对象.
     版本V1.1添加私有属性_isScrollLoaded,用于判断后台是否响应请求并返回结果.该控件只能绑定单个元素.后期版本将实现多元素绑定.
     版本V1.0主要实现滚动条触底事件的实现,但还未判断当滚动条触底时向后台发送请求后台响应是否完成的,后期版本将实现.
六、源码:
 1 (function(global){
 2     global.ScrollLoadData = function(id,callBack){
 3         this._id = id;//需绑定scroll事件的元素id,可传入window表示将事件绑定到window上
 4         this._callBack = callBack;//scroll的回调函数,需用户自行实现
 5         this._isScrollLoaded = true;//标识数据是否加载完成
 6     };
 7     global.ScrollLoadData.prototype = {
 8         constructor:global.ScrollLoadData,
 9         scrollLoadData:function(){
10             var dom,that=this;
11             if(this._id === window){
12                 dom = window;
13             }
14             else{
15                 dom = document.getElementById(this._id)
16             }
17             if(!dom){
18                 return;
19             }
20             if(document.attachEvent){
21                 dom.attachEvent('onscroll',function(e){
22                     that._scrollHandler(e);
23                 });
24             }
25             else if(document.addEventListener){
26                 dom.addEventListener('scroll',function(e){
27                     that._scrollHandler(e);
28                 },false);
29             }
30             else{
31                 var oldOnScroll = dom.onscroll;
32                 dom.onscroll = function(e){
33                     that._scrollHandler(e);
34                     if(oldOnScroll){oldOnScroll();}
35                 };
36             }
37         },
38         getIsScrollLoaded:function(){
39             return this._isScrollLoaded;
40         },
41         setIsScrollLoaded:function(value){
42             this._isScrollLoaded = value;
43         },
44         _scrollHandler:function(e){
45             e = e || window.event;
46             if(!e){return;}
47             var target = e.srcElement || e.target;
48             var isExceed = false;
49             if(this._id === window){
50                 isExceed = (document.body.clientHeight + document.body.scrollTop) >= document.body.scrollHeight;
51             }
52             else{
53                 isExceed = (this._getHeight(target) + this._getScrollTop(target)) >= this._getScrollHeight(target);
54             }
55             if(this._callBack && isExceed && this._isScrollLoaded){
56                 this._callBack.apply(global,[e,target]);
57             }
58         },
59         _getHeight:function(target){
60             var value = (this._getStyleValue(target, 'height')).trim();
61             return value ? parseInt(value) : 0;
62         },
63         _getScrollTop:function(target){
64             return target.scrollTop;
65         },
66         _getScrollHeight:function(target){
67             return target.scrollHeight;
68         },
69         _getStyleValue:function(dom, attribute){
70             if(!dom){
71                 return "";
72             }
73             var value = dom.style.attribute;
74             if(value === undefined || value === null || value.trim() === ''){
75                 value = dom.currentStyle ? 
76                             dom.currentStyle[attribute] : document.defaultView.getComputedStyle(dom,false)[attribute];
77             }
78             return value;
79         }
80     };
81     String.prototype.trim = String.prototype.trim || function(){
82         return this.replace(/^s*(.*)s*$/g,'$1');
83     };
84 })(window);
View Code