lazyload现在网上已经用的很多(淘宝商城,新浪微博等等),先放demo:mylazyLoad.zip
效果:
【基本原理】
在有大量数据加载的页面中,我们需要一个容器,这个容器可以是浏览器窗口,也可以是页面中的一个容器,在页面加载的时候,我们可以将这容器显示之外的内容阻止其加载,当我们滚动这个容器到相应区域的时候才将该区域内容加载出来,以此达到加快浏览速度的目的。
延迟加载一般分静态和动态两种。
静态的典型例子就是淘宝商城,我们在观察淘宝商城的html时发现,其页面采用了大量的textarea来存放页面元素,我们想要把页面元素存放在html里,而又不想这些元素被解析,同时又能轻松方便的获取,textarea正好满足了这些条件(真不知道哪位牛人想到的)。
而动态的可以说就是ajax获取数据再绑定,典型例子就是新浪微博,当页面滚动到底部时触发加载函数。
我的理解是将需要延迟加载的触发元素存入一个数组中,当容器scroll/resize时遍历这个数组,如果触发元素在视窗范围内就执行加载函数,并将这个元素从数组中删除来提高效率。
【程序说明】
一般在创建实例的时候,需要定义两个属性:elems和container,elems是触发加载的元素集合,或者说是加载内容集合,container就是容器。
1.因为elems需要进行删除,所以首先需要将elems转换为数组Array。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
* @param {all} a 参数
*/
var $A = function (a){
if ( ! a) return [];
if (a instanceof Array) return a;
var arr = [],len = a.length;
if ( / string|number / .test( typeof a) || a instanceof Function || len === undefined){
arr[ 0 ] = a;
} else {
for ( var i = 0 ;i < len;i ++ ){
arr[i] = a[i];
}
}
return arr;
}
this .elems = $A( this .options.elems); /* 加载对象转换成数组 */
参数a可以是string,number,object,array,function,HTMLCollection,null。
PS:我发现object.length===undefined
2.container是容器,可以是window,也可以是页面元素,所以初始化时先判断是否是window。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
var isWin = c == window || c == doc || c == null ||! c.tagName || / body|html / i.test(c.tagName); /* 判断容器是否是window */
if (isWin)c = doc.documentElement;
this .container = c;
如果不是明确的非body/html的dom元素,将都视为容器为window。
3.获取container的显示范围,即容器相对于浏览器视窗左上角的top/bottom/left/right距离,如果是window,即浏览器视窗的大小。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
var _getContainerRange = isWin && window.innerWidth ? function (){
return {top: 0 ,left: 0 ,right:window.innerWidth,bottom:window.innerHeight}
}: function (){
return _this._getRect(c);
}
this ._refreshRange = function (){
_this.range = _getContainerRange();
}
this ._refreshRange();
/* 获取元素位置参数 */
_getRect: function (elem){
var r = elem.getBoundingClientRect(); /* 元素到窗口左上角距离 */
return {top:r.top,left:r.left,bottom:r.bottom,right:r.right}
}
获取浏览器视窗大小在IE下可以通过offsetWidth/offsetHeight获得,但非IE浏览器则略有差异,好在非IE下有innerWidth/innerHeight可以使用。另外还有dom.getBoundingClientRect()这个方法,它的作用是获得dom相对于视窗左上角的top/left/bottom/right距离,而且这个方法已经得到所有浏览器的支持,大大提高了我们的效率。
PS:getBoundingClientRect可以看下http://www.cnblogs.com/qieqing/archive/2008/10/06/1304399.html ,另外谈到IE下2px问题,因为这里我都是用这个方法来获取容器以及元素位置,所以这2px差异可以忽略,也许这不太严谨,但同时也为了提高点效率考虑。
4.接下来就是给container绑定scroll/resize事件。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
if ( ! isWin){_this._refreshRange();}
_this._doLoad();
}
this ._noWinScroll = function (){ /* 解决刷新时window滚动条定位后造成range错误bug */
_this.range = _getContainerRange();
removeEventHandler(window, " scroll " ,_this._noWinScroll);
}
this ._resizeload = function (){
_this._refreshRange();
_this._doLoad();
}
this .binder = isWin ? window : c;
if ( ! isWin)addEventHandler(window, " scroll " , this ._noWinScroll);
addEventHandler( this .binder, " scroll " , this ._scrollload);
addEventHandler( this .binder, " resize " , this ._resizeload);
container是window话,scroll是不会改变container的range的,而container是元素的话,range会随着window的scroll而改变,所以这里做分支处理。
另外当我们讲window的滚动条滚至中间位置,再F5刷新页面之后,滚动条同样会在刚刚的位置,IE下首先会将滚动条提至顶部,再定位到刚刚的位置,这样就出现了一个问题,在第一次执行lazyload的时候,container的range是window滚动条在顶部时候的值,而并非我们需要的实际值。所以我这里在非isWin情况下,给window绑定一次_noWinScroll事件,滚动条定位后删除这个事件。
5.下面讲的是具体的判断、执行
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
@lock锁定,加载过程中锁定。如果为false,执行加载;如果为true,延迟递归
*/
_doLoad: function (){
var _this = this ;
if ( ! this .lock){
this .lock = true ;
setTimeout( function (){_this._loadRun()}, 100 );
} else {
clearTimeout( this .timer);
var self = arguments.callee;
this .timer = setTimeout( function (){self.call(_this)}, 100 );
}
}
scroll事件在各个浏览器里的执行次数不同,最好的是FF,一次滚轮滚动只会执行一次,而其他浏览器或多或少的会执行多次。为了优化这点,用了一个lock判断,当在进行加载函数_loadRun时,我们锁住scroll,具体方法就是"clearTimeout(this.timer);this.timer=setTimeout(function(){_this._doLoad();},100);",使用setTimeout延迟递归_doLoad,执行第二次递归前clearTimeout上一次,这样就能保证一次滚动只执行两次,开始一次,结束一次,中间的全部锁住。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
_loadRun: function (){
var elems = this .elems;
if (elems.length){
for ( var i = 0 ;i < elems.length;i ++ ){
var rect = this ._getRect(elems[i]);
var side = this ._isRange( this ._inRange(rect));
if (side && side != 0 ){
if (side == 1 &&! this .elock){
this .elock = true ;
this ._onDataLoad(elems[i]);
elems.splice(i -- , 1 ); /* 加载完之后将该对象从队列中删除 */
} else { break ;}
}
}
if ( ! elems.length){
this ._release();
}
}
this .lock = false ;
}
var range=this.range;
var side={
v : rect.top<=range.bottom ? rect.bottom>=range.top ? "in" : "" : "bottom",/*垂直位置*/
h : rect.left<=range.right ? rect.right>=range.left ? "in" : "" : "right" /*水平位置*/
};
return side;
},
_isRange:function(side){
/*1:加载 -1:跳出循环 0:不加载执行下一个*/
return {
v:side.v ? side.v=="in"?1:-1 : 0,
h:side.h ? side.h=="in"?1:-1 : 0,
c:side.v&&side.h ? side.v=="in"&&side.h=="in"? 1:side.v!="in"?-1:0 : 0
}[this.mode||"c"]
}
这里的逻辑如下:
1)遍历elems数组,获取元素[0]的rect,根据rect和container的range做比较,判断元素[0]相对于container的位置("[top/left]","bottom/right","in")
2)再根据我们的mode获得操作类型(-1,0,1)。-1表示在容器显示范围的后面,之后的元素可以不再判断,执行跳出循环;0表示在容器显示范围的前面,不执行加载,进行下个元素的判断;1表示在显示范围内,需要加载。
3)当返回的side为1时,执行_onDataLoad(),然后从元素集合中删除该元素,用的方法是Array.splice(index,num),同时i--,使得能准确的找到下个元素。这里的elock用来锁定元素加载,主要用在动态ajax加载的时候,因为动态加载的时候,我们希望当多个元素同时存在于container以及多次触发scroll时,只执行第一个元素的加载。
4)然后进行下个元素[1]的判断,重复之前的步骤。
5)当元素集合为空时,摧毁所有的绑定。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
removeEventHandler( this .binder, " scroll " , this ._scrollload);
removeEventHandler( this .binder, " resize " , this ._resizeload);
this ._onDataEnd();
}
6._onDataLoad默认情况是静态加载。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
String.prototype.removeJS = function (){
return this .replace( / <script[^>]*?>([\w\W]*?)<\/script> / ig, "" );
}
/* 将Script字符串转换为Script对象,返回Script or false */
String.prototype.getJS = function (){
var js = this .replace( / [\s\S]*?<script[^>]*?>([\w\W]*?)<\/script>[\s\S]*? / g, " $1\r " );
if (js == this ){
return false ;
} else {
var s = document.createElement( " script " );
s.text = js;
return s;
}
}
this ._onDataLoad = this .options.ondataload || function (elem){ /* 数据加载 */
var h = elem.getElementsByTagName( " textarea " );
if (h.length){
var js = h[ 0 ].value.getJS(); /* 解决innerHTML javascript不执行的问题 */
if (js){
elem.innerHTML = h[ 0 ].value.removeJS(); /* 删除javascript字符串 */
elem.appendChild(js);
} else {
elem.innerHTML = h[ 0 ].value;
}
}
this .elock = false ;
}
这里主要说的是html里的javascript代码问题,通过innerHTML的javascript代码是不会执行的,所以在这里需要提取html里的script代码,创建一个script元素,appendChild进容器内才能执行。
【总结】
总的来说在优化上以及需求的考虑上都有了提高。也越来越喜欢用自己整理的框架去组件,这样就能做到不仅知其然而且还能知其所以然。希望今后能在算法上得到指点。
demo丑了点,大家凑合凑合(^。^)y-~~
【完整代码】
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
/* my javascript library v1.2 */
/* written by Lecaf */
/* update by 2011.4.12 */
/* 删除Script字符串内容 */
String.prototype.removeJS = function (){
return this .replace( / <script[^>]*?>([\w\W]*?)<\/script> / ig, '' );
}
/* 将Script字符串转换为Script对象,返回Script or false */
String.prototype.getJS = function (){
var js = this .replace( / [\s\S]*?<script[^>]*?>([\w\W]*?)<\/script>[\s\S]*? / g, ' $1\r ' );
if (js == this ){
return false ;
} else {
var s = document.createElement( ' script ' );
s.text = js;
return s;
}
}
/* getElementById
* @param {String} id ID值
*/
var $id = function (id){
if ( typeof id != ' undefined ' && typeof id === ' string ' ){
return document.getElementById(id);
}
return null ;
}
/* 讲参数转换为数组
* @param {all} a 参数
*/
var $A = function (a){
if ( ! a) return [];
if (a instanceof Array) return a;
var arr = [],len = a.length;
if ( / string|number / .test( typeof a) || a instanceof Function || len === undefined){
arr[ 0 ] = a;
} else {
for ( var i = 0 ;i < len;i ++ ){
arr[i] = a[i];
}
}
return arr;
}
/* 注销事件
* @param {Object} oTarget 对象
* @param {String} sEventType 事件类型
* @param {Function} fnHandler 事件方法
*/
var removeEventHandler = function (oTarget, sEventType, fnHandler) {
if (oTarget.listeners[sEventType]){
var listeners = oTarget.listeners[sEventType];
for ( var i = 0 ,fn;fn = listeners[i ++ ];){
if (fn == fnHandler){
listeners.splice( -- i, 1 );
}
}
if ( ! listeners.length && listeners[ " _handler " ]){
oTarget.removeEventListener ? oTarget.removeEventListener(sEventType, listeners[ " _handler " ], false ) : oTarget.detachEvent( ' on ' + sEventType, listeners[ " _handler " ]);
}
}
}
/* 添加事件
* @param {Object} oTarget 对象
* @param {String} sEventType 事件类型
* @param {Function} fnHandler 事件方法
*/
var addEventHandler = function (oTarget, sEventType, fnHandler) {
oTarget.listeners = oTarget.listeners || {};
var listeners = oTarget.listeners[sEventType] = oTarget.listeners[sEventType] || [];
listeners.push(fnHandler);
if ( ! listeners[ " _handler " ]){
listeners[ " _handler " ] = function (e){
var e = e || window.event;
for ( var i = 0 ,fn;fn = listeners[i ++ ];){
fn.call(oTarget,e)
}
}
oTarget.addEventListener ? oTarget.addEventListener(sEventType, listeners[ " _handler " ], false ) : oTarget.attachEvent( ' on ' + sEventType, listeners[ " _handler " ]);
}
}
/* 触发事件
* @param {Object} oTarget 对象
* @param {String} sEventType 事件类型
*/
var dispatchEventHandler = function (oTarget,sEventType){
if (oTarget.dispatchEvent){
var e = document.createEvent( ' Event ' );
e.initEvent(sEventType, true , true );
oTarget.dispatchEvent(e);
} else {
oTarget.fireEvent( ' on ' + sEventType);
}
}
/* json扩展
* @param {Object} target 目标json
* @param {Object} src 源json
*/
var extendJson = function (target,src){
for ( var para in src){
target[para] = src[para];
}
return target;
}
/* 在目标元素之后插入新元素 js自带方法: target.appendChild(newDoc);target.insertBefore(newDoc,existingChild);
* @param {Document} newEl 新元素
* @param {Document} targetEl 目标元素
*/
var insertAfter = function (newEl,targetEl){
var parentEl = targetEl.parentNode;
if (parentEl.lastChild == targetEl){
parentEl.appendChild(newEl);
} else {
parentEl.insertBefore(newEl,targetEl.nextSibling);
}
}
/* 动态加载CSS文件
* @param {String} file css路径
* @param {String} cssid css link ID
*/
var loadCSS = function (file,cssid){
var cssTag = cssid ? document.getElementById(cssid) : null ;
var head = document.getElementsByTagName( ' head ' ).item( 0 );
if (cssTag) head.removeChild(cssTag);
css = document.createElement( ' link ' );
css.href = file;
css.rel = ' stylesheet ' ;
css.type = ' text/css ' ;
if (cssid){css.id = cssid;}
head.appendChild(css);
}
/* ajax封装
* @param {Object} options 参数集
* @param {String} url 链接
* @param {String} type 传参方式 'POST' or 'GET'(默认)
* @param {Bool} async 是否异步 true异步(默认) false同步
* @param {String} dataType 返回数据类型 'html'(默认) 'xml' 'json'
* @param {Function} beforeSend 发送请求前调用函数
* @param {Function} success 请求成功后回调函数
* @param {Function} complete 请求完成后回调函数(不管成功与否)
*/
var ajaxFun = function (options){
var ajaxops = {
url: '' ,
type: ' GET ' ,
async: true ,
dataType: ' html ' ,
beforeSend: null ,
success: function (){},
complete: null
}
var ajaxops = extendJson(ajaxops,options);
if (ajaxops.url){
var xmlHttp;
try {
// Firefox, Opera 8.0+, Safari
xmlHttp = new XMLHttpRequest();
} catch (e){
// Internet Explorer
try {
xmlHttp = new ActiveXObject( ' Msxml2.XMLHTTP ' );
} catch (e){
try {
xmlHttp = new ActiveXObject( ' Microsoft.XMLHTTP ' );
} catch (e){
alert( ' 您的浏览器不支持AJAX! ' );
return false ;
}
}
}
var requestDone = false ;
if ( ! ajaxops.async && navigator.userAgent.indexOf( ' Firefox ' ) > 0 ){
xmlHttp.onload = function (){
if (( xmlHttp.status >= 200 && xmlHttp.status < 300 ) || xmlHttp.status === 304 || xmlHttp.status === 1223 || xmlHttp.status === 0 ){
var msg;
switch (ajaxops.dataType){
case ' html ' :
msg = xmlHttp.responseText;
break ;
case ' xml ' :
msg = xmlHttp.responseXML;
break ;
case ' json ' :
msg = xmlHttp.responseText;
msg = ( new Function( ' return ' + msg))();
break ;
default :
msg = xmlHttp.responseText;
break ;
}
ajaxops.success(msg);
}
if (ajaxops.complete && ! requestDone){
ajaxops.complete(msg);
requestDone = true ;
}
}
} else {
xmlHttp.onreadystatechange = function (){
if (xmlHttp.readyState === 4 ){
if (( xmlHttp.status >= 200 && xmlHttp.status < 300 ) || xmlHttp.status === 304 || xmlHttp.status === 1223 || xmlHttp.status === 0 ){
var msg;
switch (ajaxops.dataType){
case ' html ' :
msg = xmlHttp.responseText;
break ;
case ' xml ' :
msg = xmlHttp.responseXML;
break ;
case ' json ' :
msg = xmlHttp.responseText;
msg = ( new Function( ' return ' + msg))();
break ;
default :
msg = xmlHttp.responseText;
break ;
}
ajaxops.success(msg);
}
if (ajaxops.complete && ! requestDone){
ajaxops.complete(msg);
requestDone = true ;
}
}
}
}
if (ajaxops.beforeSend){
ajaxops.beforeSend();
}
xmlHttp.open(ajaxops.type,ajaxops.url,ajaxops.async);
xmlHttp.send( null );
}
}
/*
* $class 写类工具函数
* @param {Function} constructor
* @param {Object} prototype
* write by Snandy http://www.cnblogs.com/snandy/
*/
var $class = function (constructor,prototype) {
var c = constructor || function (){};
var p = prototype || {};
return function () {
for ( var atr in p) {
arguments.callee.prototype[atr] = p[atr];
}
c.apply( this ,arguments);
}
}
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
/* Lazyload v1.2 */
/* written by Lecaf */
/* update by 2011.4.8 */
var Lazyload = function (options){
this ._init(options); /* 初始化 */
this ._doLoad(); /* 第一次加载 */
if ( ! this .elems.length) this ._release(); /* 如果加载元素为空,释放 */
}
var proto = {
/* 初始化参数 */
_init: function (options){
this .binder = null ; /* 加载容器对象 */
this .range = {}; /* 加载容器显示范围 */
this .elems = []; /* 加载对象队列 */
this .container = null ;
this .mode = "" ;
this .lock = false ; /* 加载容器锁定 */
this .elock = false ; /* 加载元素锁定 */
this .timer = null ; /* _doLoad计时器 */
this .options = { /* 定制参数 */
container:window, /* 加载容器 */
elems: null , /* 加载数据集合 */
mode: " v " , /* 加载模式 v(垂直加载) h(水平加载) c(交叉加载) 默认v */
ondataload: null , /* 数据加载方式 */
ondataend: function (){} /* 数据加载完毕 */
}
extendJson( this .options,options || {});
this .elems = $A( this .options.elems); /* 加载对象转换成数组 */
this .mode = this .options.mode;
this ._onDataLoad = this .options.ondataload || function (elem){ /* 数据加载 */
var h = elem.getElementsByTagName( " textarea " );
if (h.length){
var js = h[ 0 ].value.getJS(); /* 解决innerHTML javascript不执行的问题 */
if (js){
elem.innerHTML = h[ 0 ].value.removeJS(); /* 删除javascript字符串 */
elem.appendChild(js);
} else {
elem.innerHTML = h[ 0 ].value;
}
}
this .elock = false ;
}
this ._onDataEnd = this .options.ondataend; /* 所有内容加载完执行 */
this ._initContainer( this .options.container); /* 初始化容器 */
},
/* 初始化容器 */
_initContainer: function (c){
var doc = document;
var _this = this ;
var isWin = c == window || c == doc || c == null ||! c.tagName || / body|html / i.test(c.tagName); /* 判断容器是否是window */
if (isWin)c = doc.documentElement;
this .container = c;
/* 获取容器显示范围方法 */
var _getContainerRange = isWin && window.innerWidth ? function (){
return {top: 0 ,left: 0 ,right:window.innerWidth,bottom:window.innerHeight}
}: function (){
return _this._getRect(c);
}
this ._refreshRange = function (){
_this.range = _getContainerRange();
}
this ._refreshRange();
this ._scrollload = function (){
if ( ! isWin){_this._refreshRange();}
_this._doLoad();
}
this ._noWinScroll = function (){ /* 解决刷新时window滚动条定位后造成range错误bug */
_this.range = _getContainerRange();
removeEventHandler(window, " scroll " ,_this._noWinScroll);
}
this ._resizeload = function (){
_this._refreshRange();
_this._doLoad();
}
this .binder = isWin ? window : c;
if ( ! isWin)addEventHandler(window, " scroll " , this ._noWinScroll);
addEventHandler( this .binder, " scroll " , this ._scrollload);
addEventHandler( this .binder, " resize " , this ._resizeload);
},
/* 获取元素位置参数 */
_getRect: function (elem){
var r = elem.getBoundingClientRect(); /* 元素到窗口左上角距离 */
return {top:r.top,left:r.left,bottom:r.bottom,right:r.right}
},
/* 加载判断,防止多次调用
@lock锁定,加载过程中锁定。如果为false,执行加载;如果为true,延迟递归
*/
_doLoad: function (){
var _this = this ;
if ( ! this .lock){
this .lock = true ;
setTimeout( function (){_this._loadRun()}, 100 );
} else {
clearTimeout( this .timer);
var self = arguments.callee;
this .timer = setTimeout( function (){self.call(_this)}, 100 );
}
},
/* 加载运行 */
_loadRun: function (){
var elems = this .elems;
if (elems.length){
for ( var i = 0 ;i < elems.length;i ++ ){
var rect = this ._getRect(elems[i]);
var side = this ._isRange( this ._inRange(rect));
if (side && side != 0 ){
if (side == 1 &&! this .elock){
this .elock = true ;
this ._onDataLoad(elems[i]);
elems.splice(i -- , 1 ); /* 加载完之后将该对象从队列中删除 */
} else { break ;}
}
}
if ( ! elems.length){
this ._release();
}
}
this .lock = false ;
},
/* 判断对象相对容器位置 */
_inRange: function (rect){
var range = this .range;
var side = {
v : rect.top <= range.bottom ? rect.bottom >= range.top ? " in " : "" : " bottom " , /* 垂直位置 */
h : rect.left <= range.right ? rect.right >= range.left ? " in " : "" : " right " /* 水平位置 */
};
return side;
},
_isRange: function (side){
/* 1:加载 -1:跳出循环 0:不加载执行下一个 */
return {
v:side.v ? side.v == " in " ? 1 : - 1 : 0 ,
h:side.h ? side.h == " in " ? 1 : - 1 : 0 ,
c:side.v && side.h ? side.v == " in " && side.h == " in " ? 1 :side.v != " in " ?- 1 : 0 : 0
}[ this .mode || " c " ]
},
/* 释放 */
_release: function (){
removeEventHandler( this .binder, " scroll " , this ._scrollload);
removeEventHandler( this .binder, " resize " , this ._resizeload);
this ._onDataEnd();
}
}
window.onload = function (){
var Divload = $class(Lazyload,proto);
var divload = new Divload({
elems:document.getElementById( " loadmain " ).getElementsByTagName( " div " ),
container:$id( " loadbox " ),
mode: " c "
});
var Winload = $class(Lazyload,proto);
var winload = new Winload({
elems:$id( " ajaxbox " ).getElementsByTagName( " div " ),
container:window,
ondataload: function (elem){
var othis = this ;
ajaxFun({
url: " ajax.html " ,
beforeSend: function (){
elem.getElementsByTagName( " p " )[ 0 ].style.display = "" ;
},
success: function (msg){
var box = document.getElementById( " ajaxload " );
box.innerHTML = box.innerHTML + msg;
},
complete: function (){
othis.elock = false ;
}
})
}
})
}