代码改变世界

CustomEvent

2010-04-07 17:33  BlueDream  阅读(3018)  评论(0编辑  收藏  举报

事件机制 -- 典型观察者模式. 程序设计的正确标准是松耦合,高内聚. 而观察者模式恰恰给松耦合提供了便利条件. CustomEvent又是对事件的高度封装.是用户能够自定义自己的事件. 从而达到更好的松耦合.

简单的自定义事件:

function EventTarget() {
    this._listeners = {};
};

EventTarget.prototype = {
    constructor: EventTarget,
    addListener: function(type, listener) {
        if(typeof this._listeners[type] == 'undefined') {
            this._listeners[type] = [];
        }
        this._listeners[type].push(listener);
    },
    fire: function(event) {
        if(typeof event == 'string') {
            event = { type: event};
        }
        if(!event.target) {
            event.target = this;
        }
        if(!event.type) {
            throw new Error('Event Object missing type property');
        }
        if(this._listeners[event.type] instanceof Array) {
            var listeners = this._listeners[event.type];
            for(var i = 0, len = listeners.length; i < len; i++) {
                listeners[i].call(this, event);
            }
        }
    },
    removeListener: function(type, listener) {
        if(this._listeners[type] instanceof Array) {
            var listeners = this._listeners[type];
            for(var i = 0, len = listeners.length;i < len; i++) {
                if(listeners[i] === listener) {
                    listeners.splice(i, 1);
                    break;
                }
            }
        }
    }
};

//var target = new EventTarget();
//function handleEvent(event) {
    //alert(event.target);
//};

//target.addListener('foo', handleEvent);
//target.fire({type:'foo', target:'wasai'});
//target.removeListener('foo', handleEvent)
//target.fire({type:'foo', target:'wasai'});

function MyObject() {
    EventTarget.call(this);
}
MyObject.prototype = new EventTarget();
MyObject.prototype.constructor = MyObject;

MyObject.prototype.foo = function() {
    this.fire('foo');
}
var o = new MyObject();
o.addListener('foo', function() {
    alert('Foo Just happend');
})
o.foo();

上面代码主要分为三部分

1. addListener(添加事件句柄)

首先初始化的时候维护一个_listeners的Hash列表. 当追加自定义事件的时候.如果该事件没有追加过即undefined那么就创建一个数组列表用来存放事件句柄.否则如果已经存在那么就继续push到这个句柄存放数组中.

2. fire(触发事件)

如果event参数是string类型 那么给赋值为具有type属性的对象. 如果不存在target那么再往对象上添加target属性.并指向事件管理器. 然后获取当前事件数组里存放的所有句柄.循环执行.并将scope指向时间管理器.

3. removeListener(移除事件)

获取指定type的事件对象的句柄数组.循环这个数组.然后和指定的事件句柄函数做比较.如果找到了对应的事件句柄.那么就将这个事件句柄从数组中移除.

 

所以说自定义事件.简单的实现很容易.具体复杂的还需要好好挖掘.