看標題好像非常高大威猛的樣子?,且不要被題目嚇到,或許這個技巧很多朋友在工作中都運用過,只是可能不夠完善或者不care這種寫法屬於什麼設計模式。
是的,我們的目的很明確,就是DRY——Don't repeat yourself!
文章開頭,我們想來點一下題,什麼是策略模式?
策略模式的定義:每個策略中定義一系列的演算法,把它們一個個封裝起來,並且使它們可以相互替換。
好吧,我已開始也是被這個定義嚇尿了。簡單地舉個栗子說,就是你下班回家,可以走路、騎車、坐車、開車、開飛機等,每種方式都是一個策略,在程式碼裡就可以將每個策略寫成一個個的方法,方便管理。這樣就不用使用一大堆判斷語句了,難看而且不好維護。
我們今天講的是技巧,在這裡就不得不說到事件委託——又是一個高大威猛的概念(概念雖好,其實在程式碼裡就很好理解,不信接著看)
沒有場景的程式碼都是耍流氓!
場景很簡單,就是點選“已有賬號,立即登入”切換到登入,點選“還沒有賬號”切換到註冊
有些小夥伴一下就明白了怎麼回事,不就是個點選切換嘛!誒,是滴,就是這麼簡單,但我們就是喜歡吃豬蹄吃出熊掌的感覺?
寫兩個簡單的div代替一下(其中class中的hide代表隱藏的css):
<div id="login-box">
這是個登入框
<span id="goToRegister">還沒有賬號?馬上註冊</span
</div>
<div id="register-box" class="hide">
這是個註冊框
<span id="goToLogin">已有賬號,立即登入</span
</div>
複製程式碼
善用jQuery的小夥伴們一下子就想到了該怎麼寫:
$('#goToRegister').click(function () {
$('#login-box').addClass('hide')
.siblings('#register-box').removeClass('hide');
});
$('#goToLogin').click(function () {
$('#register-box').addClass('hide')
.siblings('#login-box').removeClass('hide');
});
複製程式碼
不得不佩服jQuery,簡單明瞭。但是這樣寫有一個很大的問題,就是頁面如果有很多的點選事件的時候,難道也要去一個一個複製貼上類似的程式碼嗎?還是那句話——don't repeat youself!
還記得我們剛才提到過的事件委託嗎?還不清楚什麼是事件委託還是要去搜一下,簡單的理解就是所有子元素的相同事件都委託到父元素。
$('body').on("click",function (e) {
if (e.target.id === 'goToLogin') {
$('#register-box').addClass('hide')
.siblings('#login-box').removeClass('hide');
} else if (e.target.id === 'goToRegister') {
$('#login-box').addClass('hide')
.siblings('#register-box').removeClass('hide');
}
})
複製程式碼
是的,這就是事件委託,把兩個點選事件都委託給body。為什麼要用事件委託呢,一方面是好看(可讀性高),不用像上面的程式碼一樣複製那麼多的事件程式碼;另一方面是效能,因為掛載事件的時候是很消耗效能的,一兩個事件可能不覺得,一旦有個幾十上百個事件(比如說列表)的時候,你就會臉上笑嘻嘻,心裡媽賣批。
程式碼好像稍稍完善了一丟丟,但是!就像上面說的,一旦有很多的而且是不一樣子元素的事件的時候,你就要寫很多很多判斷語句,這是我們萬萬不想看到的,這個時候我們就要想想有沒有什麼設計模式來解決此類問題。對,策略模式。
很明顯這裡有兩種策略:跳到登入或者跳到註冊
var cutOver = {
goToLogin: function () { //跳到登入
$('#register-box').addClass('hide')
.siblings('#login-box').removeClass('hide');
},
goToRegister: function () { //跳到註冊
$('#login-box').addClass('hide')
.siblings('#register-box').removeClass('hide');
}
};
複製程式碼
說到策略這個詞,我們不得不聯想到執行者,那麼在這裡的執行者是誰呢?我們要寫一個去執行策略的方法:
var eventProxy = function (command) {
cutOver[command] && cutOver[command]();
//command存在的時候才執行策略
};
複製程式碼
最後就是策略模式的事件委託:
$('body').on("click",function (e) {
eventProxy(e.target.id);
});
複製程式碼
寫到這裡其實就算結束了。慢著!說好的技巧呢?聰明的你會注意到我在策略物件裡的方法名其實是兩個div的id。所以,最大的技巧既不是策略模式,也不是事件委託,而是這個相當於粘合劑一樣的小技巧,是它把策略模式和事件委託很好的聯絡到一起。