閱讀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 你忙吧 不打擾你了