本文介绍一个jquery的小技巧,能让任意组件对象都能支持类似DOM的事件管理,也就是说除了派发事件,添加或删除事件监听器,还能支持事件冒泡,阻止事件默认行为等等。在jquery的帮助下,使用这个方法来管理普通对象的事件就跟管理DOM对象的事件一模一样,虽然在最后当你看到这个小技巧的具体内容时,你可能会觉得原来如此或者不过如此,但是我觉得如果能把普通的发布-订阅模式的实现改成DOM类似的事件机制,那开发出来的组件一定会有更大的灵活性和扩展性,而且我也是第一次使用这种方法(见识太浅的原因),觉得它的使用价值还蛮大的,所以就把它分享出来了。
在正式介绍这个技巧之前,得先说一下我之前考虑的一种方法,也就是发布-订阅模式,看看它能解决什么问题以及它存在的问题。
1. 发布-订阅模式
很多博客包括书本上都说javascript要实现组件的自定义事件的话,可以采用发布-订阅模式,起初我也是坚定不移地这么认为的,于是用jquery的$.Callbacks写了一个:
define(function(require, exports, module) {
var $ = require(jquery);
var Class = require(./class);
function isFunc(f) {
return Object.prototype.toString.apply(f) === [object Function];
}
/**
* 这个基类可以让普通的类具备事件驱动的能力
* 提供类似jq的on off trigger方法,不考虑one方法,也不考虑命名空间
* 举例:
* var e = new EventBase();
* e.on(load, function(){
* console.log(loaded);
* });
* e.trigger(load);//loaded
* e.off(load);
*/
var EventBase = Class({
instanceMembers: {
init: function () {
this.events = {};
//把$.Callbacks的flag设置成一个实例属性,以便子类可以覆盖
this.CALLBACKS_FLAG = unique;
},
on: function (type, callback) {
type = $.trim(type);
//如果type或者callback参数无效则不处理
if (!(type