标签:javascript事件处理 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");
// 报异常$.trigger is not a function $.bind("self-event",function(){alert(11);}); $.trigger("self-event");
<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,可以看到源码非常的简短,也很容易看懂。
/*! * 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篇文章:
Extending Your jQuery Application with Amplify.js
版权声明:本文为博主原创文章,未经博主允许不得转载。
使用AmplifyJS和JQuery编写更好更优雅的javascript事件处理代码
标签:javascript事件处理 jquery事件处理 javascript发布订阅模式
原文地址:http://blog.csdn.net/aitangyong/article/details/46713253