zoukankan      html  css  js  c++  java
  • 使用AmplifyJS和JQuery编写更好更优雅的javascript事件处理代码

    事件(或消息)是一种经常使用的软件设计模式。可以减少消息处理者和消息公布者的之间的耦合,比方J2EE里面的JMS规范。设计模式中的观察者模式(也叫公布/订阅模式)。这对于javascript代码相同适用。之前写的JQuery相关博客中。具体介绍了JQuery的事件处理机制和特性,具体可以參考这个文件夹下的文章。


    JQuery事件处理事实上就是使用了公布/订阅模式,包含它提供的命名空间机制、自己定义事件都非常的棒,可是JQuery事件处理有一个缺陷:JQuery事件都是和DOM元素相关的,可是非常多时候我们并不须要DOM元素。仅仅希望使用事件的公布/订阅这样的机制。

    代码1:假设某个DOM元素不存在。那么不能依靠它使用事件的公布和订阅。

    // not-exsit不存在的dom元素,事件处理无效
     $("not-exsit").bind("self-event",function(){alert(11);});
     $("not-exsit").trigger("self-event");

    代码2:JQuery并没有提供全局的bind/trigger。以下代码会报错。

    // 报异常$.trigger is not a function
      $.bind("self-event",function(){alert(11);});
      $.trigger("self-event");


    通过上面的代码1和代码2,我们就能够看出JQuery事件的不足之处了。我们能够在项目中使用AmplifyJS框架,就能够解决上面的问题。

    AmplifyJS官网http://amplifyjs.com/ 和代码下载地址http://www.bootcdn.cn/amplifyjs/

    <script src="amplify.js"></script>
    <script>
    	amplify.subscribe( "self-event", function(context){
    		console.log("priority=5,data="+JSON.stringify(context));
    	}, 5);
    	
    	
    	amplify.subscribe( "self-event", function(context){
    		console.log("priority=6,data="+JSON.stringify(context));
    	}, 6); 
      
    	amplify.subscribe( "self-event", function(context){
    		console.log("priority=3,data="+JSON.stringify(context));
    	}, 3);
      
      
      amplify.publish("self-event",{data:11});
      
    </script>
    这段代码能够正常的执行,通过AmplifyJS的使用方式能够看到。它刚好弥补了JQuery事件处理的不足。


    以下附上AmplifyJS的源代码amplify.core.js。能够看到源代码非常的简短,也非常easy看懂。

    /*!
     * Amplify Core 1.1.2
     *
     * Copyright 2011 - 2013 appendTo LLC. (http://appendto.com/team)
     * Dual licensed under the MIT or GPL licenses.
     * http://appendto.com/open-source-licenses
     *
     * http://amplifyjs.com
     */
    (function( global, undefined ) {
    
    var slice = [].slice,
    	subscriptions = {};
    
    var amplify = global.amplify = {
    	publish: function( topic ) {
    		if ( typeof topic !== "string" ) {
    			throw new Error( "You must provide a valid topic to publish." );
    		}
    
    		var args = slice.call( arguments, 1 ),
    			topicSubscriptions,
    			subscription,
    			length,
    			i = 0,
    			ret;
    
    		if ( !subscriptions[ topic ] ) {
    			return true;
    		}
    
    		topicSubscriptions = subscriptions[ topic ].slice();
    		for ( length = topicSubscriptions.length; i < length; i++ ) {
    			subscription = topicSubscriptions[ i ];
    			ret = subscription.callback.apply( subscription.context, args );
    			if ( ret === false ) {
    				break;
    			}
    		}
    		return ret !== false;
    	},
    
    	subscribe: function( topic, context, callback, priority ) {
    		if ( typeof topic !== "string" ) {
    			throw new Error( "You must provide a valid topic to create a subscription." );
    		}
    
    		if ( arguments.length === 3 && typeof callback === "number" ) {
    			priority = callback;
    			callback = context;
    			context = null;
    		}
    		if ( arguments.length === 2 ) {
    			callback = context;
    			context = null;
    		}
    		priority = priority || 10;
    
    		var topicIndex = 0,
    			topics = topic.split( /s/ ),
    			topicLength = topics.length,
    			added;
    		for ( ; topicIndex < topicLength; topicIndex++ ) {
    			topic = topics[ topicIndex ];
    			added = false;
    			if ( !subscriptions[ topic ] ) {
    				subscriptions[ topic ] = [];
    			}
    
    			var i = subscriptions[ topic ].length - 1,
    				subscriptionInfo = {
    					callback: callback,
    					context: context,
    					priority: priority
    				};
    
    			for ( ; i >= 0; i-- ) {
    				if ( subscriptions[ topic ][ i ].priority <= priority ) {
    					subscriptions[ topic ].splice( i + 1, 0, subscriptionInfo );
    					added = true;
    					break;
    				}
    			}
    
    			if ( !added ) {
    				subscriptions[ topic ].unshift( subscriptionInfo );
    			}
    		}
    
    		return callback;
    	},
    
    	unsubscribe: function( topic, context, callback ) {
    		if ( typeof topic !== "string" ) {
    			throw new Error( "You must provide a valid topic to remove a subscription." );
    		}
    
    		if ( arguments.length === 2 ) {
    			callback = context;
    			context = null;
    		}
    
    		if ( !subscriptions[ topic ] ) {
    			return;
    		}
    
    		var length = subscriptions[ topic ].length,
    			i = 0;
    
    		for ( ; i < length; i++ ) {
    			if ( subscriptions[ topic ][ i ].callback === callback ) {
    				if ( !context || subscriptions[ topic ][ i ].context === context ) {
    					subscriptions[ topic ].splice( i, 1 );
    					
    					// Adjust counter and length for removed item
    					i--;
    					length--;
    				}
    			}
    		}
    	}
    };
    
    }( this ) );


    更具体的API使用,能够參考以下这2篇文章:

    AmplifyJS源代码简析:事件分发

    Extending Your jQuery Application with Amplify.js


  • 相关阅读:
    Python 存储引擎 数据类型 主键
    Python 数据库
    Python 线程池进程池 异步回调 协程 IO模型
    Python GIL锁 死锁 递归锁 event事件 信号量
    Python 进程间通信 线程
    Python 计算机发展史 多道技术 进程 守护进程 孤儿和僵尸进程 互斥锁
    Python 异常及处理 文件上传事例 UDP socketserver模块
    Python socket 粘包问题 报头
    Django基础,Day7
    Django基础,Day6
  • 原文地址:https://www.cnblogs.com/yxwkf/p/5373431.html
Copyright © 2011-2022 走看看