源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

自己动手实现jQuery Callbacks完整功能代码详解

  • 时间:2022-02-25 00:17 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:自己动手实现jQuery Callbacks完整功能代码详解
用法和$.Callbacks完全一致 , 但是只是实现了add , remove , fire , empty, has和带参数的构造函数功能,  $.Callbacks 还有disable,disabled, fireWith , fired , lock, locked 方法  代码如下:  
[u]复制代码[/u] 代码如下:
 String.prototype.trim = function ()         {             return this.replace( /^\s+|\s+$/g, '' );         };         // Simulate jQuery.Callbacks object         function MyCallbacks( options )         {             var ops = { once: false, memory: false, unique: false, stopOnFalse: false };             if ( typeof options === 'string' && options.trim() !== '' )             {                 var opsArray = options.split( /\s+/ );                 for ( var i = 0; i < options.length; i++ )                 {                     if ( opsArray[i] === 'once' )                         ops.once = true;                     else if ( opsArray[i] === 'memory' )                         ops.memory = true;                     else if ( opsArray[i] === 'unique' )                         ops.unique = true;                     else if ( opsArray[i] === 'stopOnFalse' )                         ops.stopOnFalse = true;                 }             }             var ar = [];             var lastArgs = null;             var firedTimes = 0;             function hasName( name )             {                 var h = false;                 if ( typeof name === 'string'                     && name !== null                     && name.trim() !== ''                     && ar.length > 0 )                 {                     for ( var i = 0; i < ar.length; i++ )                     {                         if ( ar[i].name === name )                         {                             h = true;                             break;                         }                     }                 }                 return h;             }             // add a function             this.add = function ( fn )             {                 if ( typeof fn === 'function' )                 {                     if ( ops.unique )                     {                         // check whether it had been added before                         if ( fn.name !== '' && hasName( fn.name ) )                         {                             return this;                         }                     }                     ar.push( fn );                     if ( ops.memory )                     {                         // after added , call it immediately                         fn.call( this, lastArgs );                     }                 }                 return this;             };             // remove a function             this.remove = function ( fn )             {                 if ( typeof ( fn ) === 'function'                     && fn.name !== ''                     && ar.length > 0 )                 {                     for ( var i = 0; i < ar.length; i++ )                     {                         if ( ar[i].name === fn.name )                         {                             ar.splice( i, 1 );                         }                     }                 }                 return this;             };             // remove all functions             this.empty = function ()             {                 ar.length = 0;                 return this;             };             // check whether it includes a specific function             this.has = function ( fn )             {                 var f = false;                 if ( typeof ( fn ) === 'function'                     && fn.name !== ''                     && ar.length > 0 )                 {                     for ( var i = 0; i < ar.length; i++ )                     {                         if ( ar[i].name === fn.name )                         {                             f = true;                             break;                         }                     }                 }                 return f;             };             // invoke funtions it includes one by one             this.fire = function ( args )             {                 if ( ops.once && firedTimes > 0 )                 {                     return this;                 }                 if ( ar.length > 0 )                 {                     var r;                     for ( var i = 0; i < ar.length; i++ )                     {                         r = ar[i].call( this, args );                         if ( ops.stopOnFalse && r === false )                         {                             break;                         }                     }                 }                 firedTimes++;                 if ( ops.memory )                 {                     lastArgs = args;                 }                 return this;             };         };  
 测试函数如下:(注意fn1 fn2是匿名函数, fn2返回false , fn3是有“名”函数)  
[u]复制代码[/u] 代码如下:
 var fn1 = function ( v )         {             console.log( 'fn1 ' + ( v || '' ) );         };         var fn2 = function ( v )         {             console.log( 'fn2 ' + ( v || '' ) );             return false;         };         function fn3( v )         {             console.log( 'fn3 ' + ( v || '' ) );         };  
 1 . 测试add & fire var cb=new MyCallbacks(); cb.add(fn1) cb.add(fn2) cb.add(fn3) cb.fire('hello') 输出: fn1 hello fn2 hello fn3 hello 2.测试remove var cb=new MyCallbacks(); cb.add(fn1) cb.add(fn2) cb.add(fn3) cb.remove(fn1) cb.fire('hello') cb.remove(fn3) cb.fire('hello') 输出: fn1 hello fn2 hello fn3 hello ---------------------------- fn1 hello fn2 hello 2.测试has var cb=new MyCallbacks(); cb.add(fn1) cb.add(fn2) cb.add(fn3) cb.has(fn1)  cb.has(fn3)  输出: false --------------- true 3.测试带参数的构造函数 : once var cb=new MyCallbacks('once') cb.add(fn1) cb.fire('hello') cb.fire('hello') cb.add(fn2) cb.fire('hello') 输出: hello ------------------- ------------------ ------------------------------ 4.测试带参数的构造函数 : memory  var cb=new MyCallbacks('memory') cb.add(fn1) cb.fire('hello') // 输出 : fn1 hello cb.add(fn2) // 输出 : fn2 hello cb.fire('hello')  输出 :  fn1 hello  fn2 hello 5.测试带参数的构造函数 : stopOnFalse var cb=new MyCallbacks('stopOnFalse') cb.add(fn1) cb.add(fn2) cb.add(fn3) cb.fire('hello') 输出: fn1 hello fn2 hello 6.测试带参数的构造函数 :unique var cb=new MyCallbacks('unique')   b.add(fn3) b.add(fn3) cb.fire('hello') 输出: fn3 hello   7. 测试带组合参数的构造函数:四个设置参数可以随意组合,一下只测试全部组合的情况, 不然要写16个测试用例 T_T var cb=new MyCallbacks('once memory unique stopOnFalse') cb.add(fn1) // 输出: fn1 cb.add(fn2) // 输出: fn2 cb.add(fn3) //  输出: fn3 cb.fire('hello') 输出: fn1 hello fn2 hello cb.fire('hello') // 输出:没有输出   以下是官方API 文档: Description: A multi-purpose callbacks list object that provides a powerful way to manage callback lists.The $.Callbacks() function is internally used to provide the base functionality behind the jQuery $.ajax() and$.Deferred() components. It can be used as a similar base to define functionality for new components. 构造函数 : jQuery.Callbacks( flags ) flags Type: String An optional list of space-separated flags that change how the callback list behaves. Possible flags: once: Ensures the callback list can only be fired once (like a Deferred). memory: Keeps track of previous values and will call any callback added after the list has been fired right away with the latest "memorized" values (like a Deferred). unique: Ensures a callback can only be added once (so there are no duplicates in the list). stopOnFalse: Interrupts callings when a callback returns false. By default a callback list will act like an event callback list and can be "fired" multiple times. Two specific methods were being used above: .add() and .fire(). The .add() method supports adding new callbacks to the callback list, while the .fire() method executes the added functions and provides a way to pass arguments to be processed by the callbacks in the same list. 利用Callbacks 实现发布订阅模式 pub/sub: (官方文档)
[u]复制代码[/u] 代码如下:
var topics = {};         jQuery.Topic = function ( id )         {             var callbacks,                 method,                 topic = id && topics[id];             if ( !topic )             {                 callbacks = jQuery.Callbacks();                 topic = {                     publish: callbacks.fire,                     subscribe: callbacks.add,                     unsubscribe: callbacks.remove                 };                 if ( id )                 {                     topics[id] = topic;                 }             }             return topic;         };
使用
[u]复制代码[/u] 代码如下:
$.Topic( 'mailArrived' ).subscribe( function ( e )         {             console.log( 'Your have new email! ' );             console.log( "mail title : " + e.title );             console.log( "mail content : " + e.content );         }         );         $.Topic( 'mailArrived' ).publish( { title: 'mail title', content: 'mail content' } );
实现了其余的全部功能 :callbacks.disable , callbacks.disabled,   callbacks.fired,callbacks.fireWith, callbacks.lock, callbacks.locked ,然后重构了下代码结构, 将实现放入了匿名函数内, 然后通过工厂方法 window.callbacks 返回实例,以免每次使用必须 new . 具体代码如下, 有兴趣和时间的可以对照jQuery版本的Callbacks对比下 :
[u]复制代码[/u] 代码如下:
( function ( window, undefined )         {             // Simulate jQuery.Callbacks object             function Callbacks( options )             {                 var ops = { once: false, memory: false, unique: false, stopOnFalse: false },                     ar = [],                     lastArgs = null,                     firedTimes = 0,                     _disabled = false,                     _locked = false;                 if ( typeof options === 'string' && options.trim() !== '' )                 {                     var opsArray = options.split( /\s+/ );                     for ( var i = 0; i < options.length; i++ )                     {                         if ( opsArray[i] === 'once' )                             ops.once = true;                         else if ( opsArray[i] === 'memory' )                             ops.memory = true;                         else if ( opsArray[i] === 'unique' )                             ops.unique = true;                         else if ( opsArray[i] === 'stopOnFalse' )                             ops.stopOnFalse = true;                     }                 }                 function hasName( name )                 {                     var h = false;                     if ( typeof name === 'string'                         && name !== null                         && name.trim() !== ''                         && ar.length > 0 )                     {                         for ( var i = 0; i < ar.length; i++ )                         {                             if ( ar[i].name === name )                             {                                 h = true;                                 break;                             }                         }                     }                     return h;                 }                 // add a function                 this.add = function ( fn )                 {                     if ( typeof fn === 'function' )                     {                         if ( ops.unique )                         {                             // check whether it had been added before                             if ( fn.name !== '' && hasName( fn.name ) )                             {                                 return this;                             }                         }                         ar.push( fn );                         if ( ops.memory )                         {                             // after added , call it immediately                             fn.call( this, lastArgs );                         }                     }                     return this;                 };                 // remove a function                 this.remove = function ( fn )                 {                     if ( typeof ( fn ) === 'function'                         && fn.name !== ''                         && ar.length > 0 )                     {                         for ( var i = 0; i < ar.length; i++ )                         {                             if ( ar[i].name === fn.name )                             {                                 ar.splice( i, 1 );                             }                         }                     }                     return this;                 };                 // remove all functions                 this.empty = function ()                 {                     ar.length = 0;                     return this;                 };                 // check whether it includes a specific function                 this.has = function ( fn )                 {                     var f = false;                     if ( typeof ( fn ) === 'function'                         && fn.name !== ''                         && ar.length > 0 )                     {                         for ( var i = 0; i < ar.length; i++ )                         {                             if ( ar[i].name === fn.name )                             {                                 f = true;                                 break;                             }                         }                     }                     return f;                 };                 this.disable = function ()                 {                     _disabled = true;                     return this;                 };                 this.disabled = function ()                 {                     return _disabled;                 };                 this.fired = function ()                 {                     return firedTimes > 0;                 };                 function _fire( context, args )                 {                     if ( _disabled || ops.once && firedTimes > 0 || _locked )                     {                         return;                     }                     if ( ar.length > 0 )                     {                         var r;                         for ( var i = 0; i < ar.length; i++ )                         {                             r = ar[i].call( context, args );                             if ( ops.stopOnFalse && r === false )                             {                                 break;                             }                         }                     }                     firedTimes++;                     if ( ops.memory )                     {                         lastArgs = args;                     }                 };                 this.fireWith = function ( context, args )                 {                     context = context || this;                     _fire( context, args );                     return this;                 };                 this.fire = function ( args )                 {                     _fire( this, args );                     return this;                 };                 this.lock = function ()                 {                     _locked = true;                     return this;                 };                 this.locked = function ()                 {                     return _locked;                 };             };             // exposed to global as a factory method             window.callbacks = function ( options )             {                 return new Callbacks( options );             };         } )( window );
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部