Js 订阅-发布

 实例来自 JS设计模式开发实例 曾探

记下以后继续参悟

<div id='div1'>aaaa</div>
<script src="jquery-1.10.2.min.js"></script>
<script>
var Event = (function(){  
    var global = this,Event,_default = 'default';  
    Event = function(){ 
        var _listen,  
            _trigger,  
            _remove, 
            _slice = Array.prototype.slice, 
            _shift = Array.prototype.shift, 
            _unshift = Array.prototype.unshift,  
            namespaceCache = {},  
            _create,  
            find, 
            each = function( ary, fn ){ 
                var ret; 
                for ( var i = 0, l = ary.length; i < l; i++ ){ 
				 var n = ary[i]; 
                    ret = fn.call( n, i, n); 
                } 
                return ret; 
            };  
           _listen = function( key, fn, cache ){ 
               if ( !cache[ key ] ){ 
                   cache[ key ] = []; 
               } 
              cache[key].push( fn ); 
           };  
           _remove = function( key, cache ,fn){ 
               if ( cache[ key ] ){ 
                   if( fn ){ 
                       for( var i = cache[ key ].length; i >= 0; i-- ){ 
                           if( cache[ key ][i] === fn ){ 
                               cache[ key ].splice( i, 1 ); 
                           } 
                       } 
                   }else{ 
                       cache[ key ] = []; 
                   } 
               } 
           };  
           _trigger = function(){ 
               var cache = _shift.call(arguments), 
                     key = _shift.call(arguments), 
					  args = arguments, 
                     _self = this, 
                     ret, 
                     stack = cache[ key ]; 
 
               if ( !stack || !stack.length ){ 
                   return; 
               } 
 
               return each( stack, function(){ 
                   return this.apply( _self, args ); 
               }); 
            }; 
 
            _create = function( namespace ){ 
                var namespace = namespace || _default; 
                var cache = {}, 
                    offlineStack = [],    // 离线事件  
                    ret = { 
                        listen: function( key, fn, last ){ 
                            _listen( key, fn, cache ); //增加cache集合
                            if ( offlineStack === null ){ 
                                return; 
                            } 
                            if ( last === 'last' ){
							offlineStack.length && offlineStack.pop()(); 
                            }else{ 
							//离线事件里添加了fn()方法
                                each( offlineStack, function(){ 
                                this(); 
                            }); 
                         } 
 
                         offlineStack = null; //订阅时 离线事件清空 下次发布时triger就将会执行fn()
                     }, 
                     one: function( key, fn, last ){ 
                         _remove( key, cache ); 
                         this.listen( key, fn ,last ); 
                     }, 
                     remove: function( key, fn ){ 
                         _remove( key, cache ,fn); 
                     }, 
                     trigger: function(){ 
                         var fn, 
                             args, 
                             _self = this; 
 
                         _unshift.call( arguments, cache ); //arguments 第一个元素添加空数组cache
                         args = arguments; 
                         fn = function(){ 
                             return _trigger.apply( _self, args ); 
                         }; 
						//发布者offlineStack为一个空数组表明还没有订阅,为null时表示已经订阅
                         if ( offlineStack ){ 
                             return offlineStack.push( fn ); 
                         } 
                         return fn(); 
                      } 
				  };  
				  //namespace命名空间默认“default”,namespaceCache[ namespace ]为空时将ret赋值给他,并返回
                   return namespace ? 
                       ( namespaceCache[ namespace ] ? namespaceCache[ namespace ] :  
                            namespaceCache[ namespace ] = ret ) 
                                 : ret; 
               };  
        return { 
                create: _create, 
                one: function( key,fn, last ){ 
                    var event = this.create( ); 
                        event.one( key,fn,last ); 
                }, 
                remove: function( key,fn ){ 
                 var event = this.create( ); 
                    event.remove( key,fn ); 
                }, 
                listen: function( key, fn, last ){ 
                    var event = this.create( ); 
                        event.listen( key, fn, last ); 
                    }, 
                trigger: function(){ 
				 var event = this.create( ); 
                    event.trigger.apply( this, arguments ); 
                 } 
          }; 
    }();  
    return Event;  
})(); 

//发布
Event.trigger( 'click', 1 ); 

Event.trigger( 'click', 5 ); 

//订阅
Event.listen( 'click', function( a ){ 
    console.log( a );       // 输出:1 ,5 离线输出
}); 

Event.trigger( 'click', 6 ); //输出6
 
/************** 使用命名空间 ********************/ 
 
Event.create( 'namespace1' ).listen( 'click', function( a ){ 
    console.log( a );    // 输出:1 
}); 

 Event.create( 'namespace1' ).listen( 'click', function( a ){ 
    console.log( a );    // 输出:1 
}); 
 
 
Event.create( 'namespace1' ).trigger( 'click', 3 ); 
 
 
  Event.create( 'namespace1' ).listen( 'click', function( a ){ 
    console.log( a );    // 输出:1 
}); 

Event.create( 'namespace2' ).listen( 'click', function( a ){ 
    console.log( a );     // 输出:2 
}); 
 
Event.create( 'namespace2' ).trigger( 'click', 2 );
</script>

猜你喜欢

转载自blog.csdn.net/losedguest/article/details/82261435