阅读113 返回首页    go 阿里云 go 技术社区[云栖]


百度有啊前端框架分析(自定义事件)

 

    今天早晨从酒店出来,外面下着鹅毛大雪,我的妈呀,我来的时候只穿了一件秋衣,昨天晚上好像所有的天气预报都没有报告今天会下雪,我操,我们的天气预报的仙人们天天在那里说的跟真的一样,这不是骗人吗,但是也没有办法,只能自己想办法怎么能事自己变得更暖和些。

 

       JavaScript中的事件也是如此,浏览器内置的事件不可能帮你把所有的事情都做了,因此遇到特殊事件,必须我们自定义把他实现,那么我们就来来看百度有啊前端JavaScript框架的自定义事件是如何实现的。

        在百度有啊的前端js框架中自定义事件对象主要定义了:
        _srcObjes:事件源集合
        _registeredEvents:事件处理器集合
        observe:用于监听事件处理器的方法
    stopObserving:停止监听事件处理器
    fireEvent:触发事件处理器
下面对这些属性和方法逐一进行分析:

 首先声明了CustEvent,并定义了用于存放事件源对象和事件处理器的两个集合对象

if (!window.CustEvent) { var CustEvent = {}; } CustEvent._srcObjs = [];//事件源对象集合 CustEvent._registeredEvents = [];//已经注册的事件以及事件处理器

在监听事件时:
1.    每个对象上可以注册多个事件
2.    每个事件可以有多个事件处理器,同名的事件处理器会被覆盖掉

 

 

CustEvent.observe = function(obj, event, fun) {
    event = event.toLowerCase().replace(/^on/g, "");//
    var objIndex = CustEvent._srcObjs.indexOf(obj);//
    if (objIndex > -1) {//如果事件源对象集合中存在参数指定的对象
        var B = CustEvent._registeredEvents[A];//这里B是一个以事件名称为键,以事件处理器集合为值的对象
        var handlers = B[event];//取得事件处理器集合
        if (handlers) {//如果该事件已经注册过处理器,会把原来的事件处理器给覆盖掉
            handlers.remove(fun);//把原来同名的处理器删除
            handlers.push(fun);//添加的新的处理器
        } else {//如果没有注册
            B[event] = [fun];
        }
    } else {//如果事件源对象集合中不存在参数指定的对象
        CustEvent._srcObjs.push(obj);
        var B = {};
        B[event] = [fun];
        CustEvent._registeredEvents.push(B);
    }
};
在停止监听时:
1.如果指定处理器名称,则只删除该处理器,否则把参数指定事件的所有处理器都删除
2.如果参数指定的对象中没有事件处理器,就把事件源和注册的事件对象全部删除。
CustEvent.stopObserving = function(obj, event, handle) {
    event = event.toLowerCase().replace(/^on/g, "");
    var objIndex = CustEvent._srcObjs.indexOf(obj);
    if (objIndex < 0) {
        return;
    }
    var eventhandlers = CustEvent._registeredEvents[objIndex];
    if (eventhandlers [event]) {
        if (handle) {//如果指定处理器,只删除指定的处理器
            eventhandlers [event].remove(handle);
        } else {//否则删除指定事件所有的处理器
            eventhandlers [event].length = 0;
        }
    }
var E = false;
//判断对象中是否还有事件处理器
    for (var D in eventhandlers) {
        if (eventhandlers [D] && eventhandlers [D].length > 0) {
            E = true;
            break;
        }
}
//如果注册的事件中没有了指定对象的处理器,就把事件源和事件对象去不删除
    if (!E) {
        CustEvent._srcObjs.removeAt(objIndex);
        CustEvent._registeredEvents.removeAt(objIndex);
    }
};
触发事件时:
1.如果是浏览器内置事件,直接只执行就可以了。
2.如果是自定义事件,那么就分别执行每个处理器。
CustEvent.fireEvent = function(obj, event) {
    var args = Array.toArray(arguments);
    args.splice(0, 2);
    args.push(event);
event = event.toLowerCase().replace(/^on/g, "");
//浏览器内置事件的处理
    if (obj["on" + event]) {
        obj["on" + event].apply(obj, args);
}
//自定义事件的处理
    var objIndex = CustEvent._srcObjs.indexOf(obj);
    if (objIndex < 0) {
        return;
}
//如果存在事件源对象
    var eventhandlers = CustEvent._registeredEvents[objIndex];
    var handlers = eventhandlers [event];//取得事件的所有处理器
    if (handlers) {//分别执行每个处理器
        for (var i = 0; i < handlers.length; i++) {
            handlers [i].apply(obj, args);
        }
    }
};
以上就是百度有啊前端js框架中的自定义事件的实现。如果大家有兴趣可以去研究下jQuery
yui中的自定义事件。(尤其是yui3.0中的自定义事件也支持捕获和冒泡,相当牛逼的)

最后更新:2017-04-02 04:01:42

  上一篇:go 2010年最新令人无语语录
  下一篇:go 你忙吧 不打扰你了