javascript 绑定切换

本文介绍了一种使用jQuery实现每次点击触发不同回调函数的方法,并提供了一个更简洁的自定义实现方案。

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();
        });
      };

用法与例子:

<!doctype html> <html lang="en"> <head> <meta charset="utf-8" /> <meta content="IE=8" http-equiv="X-UA-Compatible"/> <title>绑定切换 by 司徒正美 </title> <style type="text/css"> #box { width:200px; height:200px; border:1px solid black; position:absolute; left:20ex; top:100px; background-color:#EEE8AA; } </style> <link rel="kinetic-stylesheet" type="text/css" href="demo.kss" /> <script type="text/javascript"> 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/**/){ 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); } window.onload = function(){ var el = document.getElementById("box"); toggle(el,function(e){ alert(e.type) alert("这是回调函数一") },function(e){ alert("切换到回调函数二") },function(){ alert(this) alert("切换到回调函数三") }); } </script> </head> <body> <div id="box"></div> </body> </html>

运行代码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值