下面是对Function.prototype的扩展。
new demo.addEvent()之后,this.el并不能按我们想象的那样工作。原因就是在事件回调函数中,this指向了“demoID"那个元素。改造一下代码:
var
$
break
=
...
{}
,$
continue
=
...
{}
;
( function (s) ... {
s.bind = function()...{
var _method = this;
var args = arguments.array();
var cler = args.length>0?args.shift():window;
return function()...{
return _method.apply(cler,args.concat(arguments.array()));
}
}
s.bindAfter = function()...{
var args = arguments.array();
var func = args.length>0?args.shift():$blank;
var cler = args.length>0?args.shift():window;
return function()...{
var res = true;
var argus = args.concat(arguments.array());
res = this.apply(cler,argus);
if(res !== false)res = func.apply(cler,argus);
return res;
}.bind(this);
}
s.bindBefore = function()...{
var args = arguments.array();
var func = args.length>0?args.shift():$blank;
var cler = args.length>0?args.shift():window;
return function()...{
var argus = args.concat(arguments.array());
res = func.apply(cler,argus);
return res === false || res == "false"?res:this.apply(cler,argus);;
}.bind(this);
}
s.join = function()...{
var args = arguments.array();
var func = args.length>0?args.shift():$blank;
var str = args.length>0?args.shift():"";
return function()...{
var a = arguments.array();
var cler1 = a.length>0?a.shift():window;
var cler2 = a.length>0?a.shift():window;
var argus = args.concat(a);
var res = this.apply(cler1,argus);
var resa = func.apply(cler2,argus);
if(resa) res += str + res a;
return res;
}.bind(this);
}
s.bindAsEventListener = function(cler)...{
returen function()...{
var evt = window.event;
var doc = window.document;
if(!evt && parent && parent.frames)...{
$A(parent.frames).each(function(o)...{
try...{
if(o.window.event)...{
evt = o.window.event;
doc = o.window.document;
throw $break;
}
}catch(e)...{throw $continue;}
});
}
return this.call(cler,evt,doc);
}.bind(this);
}
s.bindAsCallBack = function()...{
var args = arguments.array();
var cler = args.length>0?args.shift():window;
var msec = args.length>0?args.shift():10;
var htis = this;
if(!this.clers)this.clers = [];
this.clers.push(...{caller:cler,id:null});
return function()...{
var argus = args.concat(arguments.array());
var callback = function()...{htis.apply(cler,argus);}
htis.clers.each(function(o)...{
if(o.caller === cler)...{
if(o.id)clearTimeout(o.id);
o.id = setTimeout(callback,msec);
}
});
}
}
s.doLater = function()...{
var args = arguments.array();
var cler = args.length>0?args.shift():window;
var msec = args.length>0?args.shift():window;
if(!this.$runers)this.$runers = [];
this.$runers.remove(function(o)...{
if(o.cler === cler && o.args.equalsV(args)...{
clearTimeout(o.id);
return true;
}else return fals;
});
var callback = function()...{
this.apply(cler,args);
this.$runers.remove(function(o)...{return o.id === callback.ID;});
}.bind(this);
callback.ID = setTimeout(callback,msec);
this.$runers.push(...{id:callback.ID,cler:cler,args:args});
return callback.ID;
}
s.clearTime = function()...{
if(this.$runers && this.$runers.length>0)...{
var args = arguments.array();
var cler = args.length>0?args.shift():window;
this.$runers.remove(function(o)...{
if(o.cler == cler && args.length<1 || o.args.equalsV(args)))...{
clearTimeout(o.id);
return true;
}else return false;
}
}
}
s.doNow = function()...{
var args = arguments.array();
var cler = args.length>0?args.shift():window;
if(this.$runers && this.runers.length>0)...{
this.$runers.remove(function(o)...{
if(o.cler === cler && args.length <1 || o.args.equalsV(args)))...{
clearTimeout(o.id);
this.apply(o.cler,o.args);
return true;
}else return false;
}.bind(this));
}else if(!this.$runers)this.apply(cler,args);
}
} )(Function.prototype);
( function (s) ... {
s.bind = function()...{
var _method = this;
var args = arguments.array();
var cler = args.length>0?args.shift():window;
return function()...{
return _method.apply(cler,args.concat(arguments.array()));
}
}
s.bindAfter = function()...{
var args = arguments.array();
var func = args.length>0?args.shift():$blank;
var cler = args.length>0?args.shift():window;
return function()...{
var res = true;
var argus = args.concat(arguments.array());
res = this.apply(cler,argus);
if(res !== false)res = func.apply(cler,argus);
return res;
}.bind(this);
}
s.bindBefore = function()...{
var args = arguments.array();
var func = args.length>0?args.shift():$blank;
var cler = args.length>0?args.shift():window;
return function()...{
var argus = args.concat(arguments.array());
res = func.apply(cler,argus);
return res === false || res == "false"?res:this.apply(cler,argus);;
}.bind(this);
}
s.join = function()...{
var args = arguments.array();
var func = args.length>0?args.shift():$blank;
var str = args.length>0?args.shift():"";
return function()...{
var a = arguments.array();
var cler1 = a.length>0?a.shift():window;
var cler2 = a.length>0?a.shift():window;
var argus = args.concat(a);
var res = this.apply(cler1,argus);
var resa = func.apply(cler2,argus);
if(resa) res += str + res a;
return res;
}.bind(this);
}
s.bindAsEventListener = function(cler)...{
returen function()...{
var evt = window.event;
var doc = window.document;
if(!evt && parent && parent.frames)...{
$A(parent.frames).each(function(o)...{
try...{
if(o.window.event)...{
evt = o.window.event;
doc = o.window.document;
throw $break;
}
}catch(e)...{throw $continue;}
});
}
return this.call(cler,evt,doc);
}.bind(this);
}
s.bindAsCallBack = function()...{
var args = arguments.array();
var cler = args.length>0?args.shift():window;
var msec = args.length>0?args.shift():10;
var htis = this;
if(!this.clers)this.clers = [];
this.clers.push(...{caller:cler,id:null});
return function()...{
var argus = args.concat(arguments.array());
var callback = function()...{htis.apply(cler,argus);}
htis.clers.each(function(o)...{
if(o.caller === cler)...{
if(o.id)clearTimeout(o.id);
o.id = setTimeout(callback,msec);
}
});
}
}
s.doLater = function()...{
var args = arguments.array();
var cler = args.length>0?args.shift():window;
var msec = args.length>0?args.shift():window;
if(!this.$runers)this.$runers = [];
this.$runers.remove(function(o)...{
if(o.cler === cler && o.args.equalsV(args)...{
clearTimeout(o.id);
return true;
}else return fals;
});
var callback = function()...{
this.apply(cler,args);
this.$runers.remove(function(o)...{return o.id === callback.ID;});
}.bind(this);
callback.ID = setTimeout(callback,msec);
this.$runers.push(...{id:callback.ID,cler:cler,args:args});
return callback.ID;
}
s.clearTime = function()...{
if(this.$runers && this.$runers.length>0)...{
var args = arguments.array();
var cler = args.length>0?args.shift():window;
this.$runers.remove(function(o)...{
if(o.cler == cler && args.length<1 || o.args.equalsV(args)))...{
clearTimeout(o.id);
return true;
}else return false;
}
}
}
s.doNow = function()...{
var args = arguments.array();
var cler = args.length>0?args.shift():window;
if(this.$runers && this.runers.length>0)...{
this.$runers.remove(function(o)...{
if(o.cler === cler && args.length <1 || o.args.equalsV(args)))...{
clearTimeout(o.id);
this.apply(o.cler,o.args);
return true;
}else return false;
}.bind(this));
}else if(!this.$runers)this.apply(cler,args);
}
} )(Function.prototype);
简单介绍:
1、bind:将一个方法绑定到某个对象上,使该方法中的this指向该对象。
许多JS程序员常常苦恼于this的指向经常被javascript的内部规则所改变,有时候,this表示调用者,有时候,this表示事件发生者。这些“潜规则”往往让代码的可读性大大降低。如:
var demo
=
Class.extend(
...
{
construct:function()...{
this.el = document.getElementByID("demoID");
this.tit = "DeomTit";
}
addEvent:function()...{
this.el.onmouseover = function()...{
this.el.title = this.tit;
}
}
} );
construct:function()...{
this.el = document.getElementByID("demoID");
this.tit = "DeomTit";
}
addEvent:function()...{
this.el.onmouseover = function()...{
this.el.title = this.tit;
}
}
} );
addEvent:
function
()
...
{
this.el.onmouseover = function()...{
this.el.title = this.tit;
}.bind(this);
}
this.el.onmouseover = function()...{
this.el.title = this.tit;
}.bind(this);
}
new demo.addEvent()终于可以按照我们的想法工作了。
(待续)