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


  • 相关阅读:
    cmake Found package configuration file but it set OpenCV_FOUND to FALSE
    pthread库"timespec"结构体重定义解决
    【Windows10】运行软件后,窗口不显示的解决办法
    Windows下Cmake生成动态库install命令失败、导入库概念
    【转载】多尺度增强算法Retinex算法(MSRCR)的原理、实现及应用
    【转载】Ubuntu 和 Windows 之间进行远程访问和文件互传
    博客园Markdown编辑器
    合并两个有序数组(C++)
    从协方差矩阵的估算领会MATLAB矩阵编程思维
    常见排序算法的性能对比
  • 原文地址:https://www.cnblogs.com/yxwkf/p/5373431.html
Copyright © 2011-2022 走看看