jQuery有关事件绑定的函数太丰富了,今天由于某需求,需要一种每次点击触发不同的回调函数的效果,因此瞄一瞄jQuery的API,发现toggle正是我要的,于是也给我框架添一个。但jQuery的实现太复杂了,闭包套嵌过多,我换另一种思路轻松实现了它。
下面是jQuery的实现:
//===============代理函数===============
proxy: function( fn, proxy, thisObject ) {
if ( arguments.length === 2 ) {
if ( typeof proxy === "string" ) {
thisObject = fn;
fn = thisObject[ proxy ];
proxy = undefined;
} else if ( proxy && !jQuery.isFunction( proxy ) ) {
thisObject = proxy;
proxy = undefined;
}
}
if ( !proxy && fn ) {
proxy = function() {
return fn.apply( thisObject || this, arguments );
};
}
// Set the guid of unique handler to the same of original handler, so it can be removed
if ( fn ) {
proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
}
// So proxy can be declared as an argument
return proxy;
},
//===============绑定切换函数===============
toggle: function( fn ) {
// Save reference to arguments for access in closure
var args = arguments, i = 1;
// link all the functions, so any of them can unbind this click handler
while ( i < args.length ) {
jQuery.proxy( fn, args[ i++ ] );
}
return this.click( jQuery.proxy( fn, function( event ) {
// Figure out which function to execute
var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i;
jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 );
// Make sure that clicks stop
event.preventDefault();
// and execute the function
return args[ lastToggle ].apply( this, arguments ) || false;
}));
},
这是我的实现:
toggle:function(/*fn1,fn2,fn3*/){
var callback = function(event){
var self = arguments.callee;
try{
self["fn"+self._toggle].call(this,event)
}catch(e){
self._toggle =0 ;
self["fn"+self._toggle].call(this,event)
}
self._toggle ++
}
for(var i=0;i<arguments.length;i++){
callback["fn"+i] = arguments[i];
}
return this.click(callback)
}
由于我不可能把我的事件模块放出来,它与jQuery的事件模块一样精致与复杂,换言之,一样易碎,强行分割就动弹不了。不过结合我早期放出的addEvent函数,还是能做出来的,虽然事件队列与事件对象还没有现整化。
var addEvent = function(el, type, fn) {
if (el.addEventListener) {
el.addEventListener(type, fn, false);//DOM2.0
}else if (el.attachEvent) {
el.attachEvent('on' + type, function(){
fn.call(el,window.event)
});
}
}
var toggle = function(el/*,fn1,fn2,fn3*/){
var callback = function(event){
var self = arguments.callee;
try{
self["fn"+self._toggle].call(this,event)
}catch(e){
self._toggle =0 ;
self["fn"+self._toggle].call(this,event)
}
self._toggle ++
}
var fns = [].slice.call(arguments,1);
for(var i=0;i<fns.length;i++){
callback["fn"+i] = fns[i];
}
addEvent(el,"click",callback);
}
//=========经群里高人指点,继续简化与优化=====
var toggle2 = function(el) {
var fns = [].slice.call(arguments, 1),
backup = fns.concat();
addEvent(el, 'click', function(e){
if (!fns.length) { fns = backup.concat()}
fns[0].call(this,e);
fns.shift();
});
};
用法与例子:
运行代码