聽飛狐聊JavaScript設計模式系列08

本回內容介紹

上一回聊到工廠模式,略抽象。
介一回,咱聊門面模式就比較容易了,門面模式也叫外觀模式(facade)。
官方說法,門面模式是指提供一個統一的接口去訪問多個子系統的多個不一樣的接口,爲子系統中的一組接口提供一個統一的高層接口。使得子系統更容易使用。
說白了,就是解耦類的接口。初次聽到這詞兒的童鞋看到代碼後估計會有親切感,開始咯:javascript

1. 門面模式

隨便想個玩意兒吧,好比一個考勤系統,一個哥們兒上班打卡,就簡單模擬實現下,敲代碼咯:html

// 定義一個接口,還記得吧,不記得就看第五回
var PersonInterface = new Interface("PersonInterface",["getInfo"]);

// 這裏簡單點,就定義一我的的類
var Person = function(name){
    this.name = name;
    this.getInfo = function(){
        return "名字:"+this.name;
    }

    // 驗證明現接口
    Interface.ensureImplements(this,PersonInterface);
}

// 定義考勤系統接口
var AttendSystemInterface = new Interface("attendSystemInterface",["records"]);
// 考勤系統
var AttendSystem = function(){
    this.attendTime = new Date().toLocaleString();
    this.records = function(){
        return "簽到時間:"+this.attendTime;
    }
    // 驗證明現接口
    Interface.ensureImplements(this,AttendSystemInterface);
}


// 這裏就是個簡單的門面客戶端,怎麼實現都在這完成
function facade(person,attendSystem){
    var res = person.getInfo()+"------"+attendSystem.records();
    alert(res);
}

// 簡單的測試一下
var fox = new Person("飛狐");
var as = new AttendSystem();
facade(fox,as);    //名字:飛狐------簽到時間:2015/11/18 下午18:08:08

這就是簡單門面模式的模擬了,比較好理解,不少網上的資料都用JS的DOM2事件例子來說的門面模式,走走過場來一個好了,看下一個例子,走你...java

2. 門面模式之DOM2事件

在DOM2級事件中的兩個方法(注:W3C,IE8及以前的瀏覽器不支持):
addEventListener(),removeEventListener()
全部DOM 節點中都包含這兩個方法,而且都接受3個參數:事件名,函數,冒泡或捕獲的布爾值(true 表示捕獲,false 表示冒泡);
在IE中實現了相似的方法:attachEvent() 和 detachEvent(),這兩個方法接受相同的參數:事件名稱和函數。瀏覽器

var EventUtil = {
    // 添加事件
    addHandler: function(el,type,fn){
        if(el.addEventListener){
            // W3C
            el.addEventListener(type,fn,false);
        }else if(el.attachEvent){
            // IE
            el.attachEvent("on"+type,fn);
        }else{
            el["on"+type] = fn;
        }
    },
    // 移除事件
    removeHandler: function(el,type,fn){
        if(el.removeEventListener){
            // W3C
            el.removeEventListener(type,fn,false);
        }else if(el.detachEvent){
            // IE
            el.detachEvent("on"+type,fn);
        }else{
            el["on"+type] = fn;
        }
    },
    /*
     * 獲取事件,這裏注意一下IE方式( window.event )獲取事件對象,
     * 可是在Firefox中會報錯,提示:window.event is undefined,
     * 說明Firefox不支持IE方式獲取事件對象而是以句柄的第一個參數傳入的
     */ 
    getEvent:function(event){
        return event?event:window.event;
    },
    /*
     * 獲取事件做用的元素
     * IE:有srcElement屬性,沒有target屬性。
     * firefox:有target屬性,沒有srcElement屬性。
     */ 
    getTarget:function(event){
        return event.target||event.srcElement;
    },
    // 取消事件的默認動做
    preventDefault:function(event){
        if(event.preventDefault){
            event.preventDefault();
        }else{    // IE阻止默認行爲
            event.returnValue = false;
        }
    },
    // 取消冒泡
    stopPropagation:function(event){
        // W3C的取消冒泡
        if(event.stopPropagation){
            event.stopPropagation();
        }else{    // IE的取消冒泡
            event.cancelBubble = true;
        }
    }

};

document.write("<button id='btn'>給飛狐點個贊</button>");
var btn = document.getElementById("btn");
EventUtil.addHandler(btn,"click",function(){
    alert("Are you ok!");
});

這個例子特簡單吧,是否有似曾相識的感受,是的,這是模擬高程3上事件的例子,這裏對事件封裝得很簡單,而在IE中還有這幾個區別:
IE 不支持捕獲,只支持冒泡;
IE 添加事件不能屏蔽重複的函數;
IE 中的 this 指向的是 window 而不是 DOM 對象;
IE 沒法接受 event 對象,但使用了 attachEvent()卻能夠,只是有區別;
咱們這裏只是聊門面模式,簡單的模擬,JS的事件系統有不少能夠細細品味的地方,之後聊到ExtJS事件系統源碼的時候還會詳細的刨根問底,好像又扯多了...函數

裝逼圖
又到裝逼時候了。雙11的價格挺誘人吧,我是沒忍住買了一個本本,尼瑪同款電腦,天貓比京東便宜860塊吖~~性能

這一回聊的內容少,難度很小,比較好理解。
下面的內容很簡單,聊一下JS的事件委託...測試

JS事件委託

高程3上對事件委託的描述是,事件委託利用了事件冒泡,只指定一個事件處理程序,就能夠管理某一類型的全部事件。接着剛剛封裝的事件例子,繼續寫:this

<ul id="ul">
  <li>飛狐</li>
  <li>帥狐</li>
  <li>飛狐就是帥</li>
</ul>
// 獲取id
function $(id){
    return document.getElementById(id);
}
var oUl = $('ul');
var oLi = oUl.getElementsByTagName("li");

// 不用事件委託,就得循環每一個子li,分別綁定事件
for(var i=0,len=oLi.length;i<len;i++){
    // 添加事件
    EventUtil.addHandler(oLi[i],'click',function(e){
        // 獲取事件
        e = EventUtil.getEvent(e);
        // 獲取事件做用的元素
        var tag = EventUtil.getTarget(e);
        alert(tag.innerHTML);
    })
}

// 用事件委託來寫,只須要在Ul上添加一個事件
EventUtil.addHandler(oUl,'click',function(e){
    e = EventUtil.getEvent(e);
    var tag = EventUtil.getTarget(e);
    alert(tag.innerHTML);
})

這個是拿書上的例子來改的,目的是爲了讓你們更方便的理解,能夠看出事件委託佔用內存少,讀取速度快,性能更高。spa

這一回,主要聊了門面模式,DOM2級事件,事件委託,難度比較小~~
下一回,聊聊代理模式,也比較簡單。firefox

客觀看完點個贊,推薦推薦唄,嘿嘿~~


注:此係飛狐原創,轉載請註明出處

相關文章
相關標籤/搜索