一、背景:
当用户信息较多,页面在展示数据时为减少加载时间,传统方法是采用分页显示,用户查看上一页数据或下一页数据时,需要来回切换,影响体验。现各大微博网站使用新方法弥补分页的不足:如数据过多,页面无法全部展示则先展示部分数据并显示滚动条,用户滑动滚动条触底时再加载部分新数据,而页面之前的数据仍将保留。
二、功能:
模拟实现各大微博网站所采用的当滚动条触底加载数据的技术。
三、说明:
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);