# Backbone入門之事件(Backbone.Events)
本系列前一篇講述了[Backbone入門之視圖](http://blog.codingplayboy.com/?p=234)鞠值,本篇繼續(xù)講述Backbone事件扯躺。
Backbone事件將事件觸發(fā)所要執(zhí)行的回調(diào)函數(shù)注冊成事件處理句柄,當(dāng)事件發(fā)生時扛吞,就觸發(fā)該函數(shù)。
## Backbone.Events
Backbone.Events可以擴(kuò)展到任何對象上议薪,使其具有綁定和觸發(fā)事件的能力罐孝。在綁定事件的回調(diào)處理函數(shù)之前,不需要定義事件雅任,且可以傳遞參數(shù):
```
? ?var myObj = {};
? ?_.extend(myObj, Backbone.Events);
? ?//添加一個自定義事件
? ?myObj.on('test', function(msg) {
? ? ? ?console.log('triggered ' + msg);
? ?});
? ?//觸發(fā)自定義事件,輸出"triggered test"
? ?myObj.trigger('test', 'test');
```
### on()
on(event, callback [,context])會在對象上綁定一個事件回調(diào)函數(shù)风范,回調(diào)函數(shù)this默認(rèn)指向當(dāng)前對象,事件發(fā)生時,回調(diào)函數(shù)就會被調(diào)用沪么。單一事件時硼婿,第一個參數(shù)event值即為自定義事件名;而多個事件時禽车,則可以為事件加上命名空間寇漫,以冒號分隔刊殉;第三個參數(shù)可以傳入作為回調(diào)函數(shù)執(zhí)行上下文,:
*注:特殊事件all州胳,可以捕獲對象上所有的事件觸發(fā)记焊。*
- 未注冊all事件
? ?```
? ? ? ?var myObj = {};
? ? ? ?_.extend(myObj, Backbone.Events);
? ? ? ?function test(msg) {
? ? ? ? ? ?console.log('triggered ' + msg);
? ? ? ?}
? ? ? ?myObj.on('test:first', test);
? ? ? ?myObj.on('test:second', test);
? ? ? ?//觸發(fā)test:first事件,輸出 "triggered test first"
? ? ? ?myObj.trigger('test:first', 'test first');
? ? ? ?//觸發(fā)test:second事件栓撞,輸出 "triggered test second"
? ? ? ?myObj.trigger('test:second', 'test second');
? ? ? ?//不觸發(fā)任何事件
? ? ? ?myObj.trigger('test', 'test');
? ?```
- 注冊all事件
? ?```
? ? ? ?var myObj = {};
? ? ? ?_.extend(myObj, Backbone.Events);
? ? ? ?function test(msg) {
? ? ? ? ? ?console.log('triggered ' + msg);
? ? ? ?}
? ? ? ?//監(jiān)聽所有事件
? ? ? ?myObj.on('all', test);
? ? ? ?//觸發(fā)test:first事件遍膜,輸出 "triggered test first"
? ? ? ?myObj.trigger('test:first', 'test first');
? ? ? ?//觸發(fā)test:second事件,輸出 "triggered test second"
? ? ? ?myObj.trigger('test:second', 'test second');
? ? ? ?//觸發(fā)test事件瓤湘, 輸出"triggered test"
? ? ? ?myObj.trigger('test', 'test');
? ?```
### once()
注冊事件并綁定回調(diào)處理函數(shù)瓢颅,觸發(fā)一次后立即被移除,其他同on()方法弛说。
### off()
off([event] [,callback] [,context])事件可以移除之前通過on()方法綁定在事件對象上的回調(diào)處理函數(shù)挽懦,第一個參數(shù)為要移除的回調(diào)函數(shù)對應(yīng)的事件名,若為空則移除所有事件的回調(diào)函數(shù)木人;第二個參數(shù)為對應(yīng)的要移除的回調(diào)函數(shù)名信柿,若為空則移除該事件所有綁定的回調(diào)函數(shù):第三個函數(shù)為回調(diào)函數(shù)上下文,若為空則移除所有上下文下的這個回調(diào)函數(shù):
```
? ?var myObj = {};
? ?_.extend(myObj, Backbone.Events);
? ?function test(msg) {
? ? ? ?console.log('triggered ' + msg);
? ?}
? ?function joke(msg) {
? ? ? ?console.log("Joke " + msg);
? ?}
? ?myObj.on('test:first', test);
? ?myObj.on('test:second', test);
? ?myObj.on('joke', test);
? ?myObj.on('joke', joke);
? ?myObj.off('test:first');
? ?//觸發(fā)test:first事件醒第,不輸出
? ?myObj.trigger('test:first', 'test first');
? ?//觸發(fā)test:second事件渔嚷,輸出 "triggered test second"
? ?myObj.trigger('test:second', 'test second');
? ?myObj.off('joke', test);
? ?//觸發(fā)joke事件,輸出"Joke joke"
? ?myObj.trigger('joke', 'joke');
? ?myObj.off('joke');
? ?//觸發(fā)joke事件稠曼,不輸出
? ?myObj.trigger('joke', 'joke');
```
### trigger()
trigger(event [,*args])方法為指定事件觸發(fā)回調(diào)函數(shù)圃伶,第一個參數(shù)為事件名,后面的參數(shù)為傳遞的參數(shù)蒲列,可以為一個或多個窒朋;trigger()方法可以觸發(fā)一個或多個事件的回調(diào)函數(shù),觸發(fā)單個事件時蝗岖,event參數(shù)值即為事件名侥猩;而觸發(fā)多個事件時,event值為以空格分隔的多個事件名:
```
? ?var myObj = {};
? ?_.extend(myObj, Backbone.Events);
? ?function test(arg1, arg2) {
? ? ? ?console.log('triggered ' + arg1 + ' ' + arg2);
? ?}
? ?function joke(msg) {
? ? ? ?console.log("Joke " + msg);
? ?}
? ?myObj.on('test', test);
? ?myObj.on('joke', joke);
? ?//輸出"triggered boy girl"
? ?myObj.trigger('test', 'boy', 'girl');
? ?//輸出"triggered several events undefined"和"Joke several events"
? ?myObj.trigger('test joke', 'several events');
```
### listenTo()
前文的on()和off()都是在對象上直接綁定或移除回調(diào)函數(shù)抵赢,而listenTo(obj, event, callback)方法則可以實現(xiàn)一個對象監(jiān)聽另一個對象上的事件欺劳,第一個參數(shù)是要監(jiān)聽的對象,第二個參數(shù)是要堅聽對象上事件的事件名铅鲤,第三個參數(shù)是所監(jiān)聽對象上事件觸發(fā)時此對象上的回調(diào)函數(shù):
*注:object.listenTo()方法調(diào)用時划提,其第三個參數(shù)回調(diào)函數(shù)執(zhí)行上下文總是當(dāng)前對象object。*
```
? ?var objA = {}, objB = {};
? ?_.extend(objA, Backbone.Events);
? ?_.extend(objB, Backbone.Events);
? ?objA.listenTo(objB, 'test', function(e) {
? ? ? ?console.log('listened it');
? ?});
? ?//輸出"listened it"
? ?objB.trigger('test');
```
### listenToOnce()
listenToOnce(obj, event, callback)方法則可以實現(xiàn)一個對象監(jiān)聽另一個對象上的事件邢享,并在該事件觸發(fā)一次后
### stopListening()
stopListening([other] [,event] [,callback])方法使對象終止監(jiān)聽事件鹏往,若不帶參數(shù),則停止監(jiān)聽所有對象骇塘,移除所有已注冊的回調(diào)函數(shù)伊履;若第二個參數(shù)為空用押,則停止監(jiān)聽某對象上所有事件篙悯,移除為該對象注冊的所有回調(diào)函數(shù)伍纫;若第三個參數(shù)為空噪沙,停止監(jiān)聽某對象上特定事件哄辣,移除為該事件注冊的所有回調(diào)函數(shù);參數(shù)均不為空溢陪,移除某對象上特定事件的指定回調(diào)函數(shù):
```
? ?var objA = {}, objB = {};
? ?_.extend(objA, Backbone.Events);
? ?_.extend(objB, Backbone.Events);
? ?objA.listenTo(objB, 'test', function(e) {
? ? ? ?console.log('listened it');
? ?});
? ?//輸出"listened it"
? ?objB.trigger('test');
? ?objA.stopListening(objB);
? ?//不輸出
? ?objB.trigger('test');
```
## 事件與視圖
在Backbone中,事件使用最多的場景總是與視圖對象一起睛廊,在一個視圖中杉编,要監(jiān)聽事件,一般有兩種方式:DOM事件和Event事件API邓馒。
- DOM事件
? ?添加DOM事件可以通過視圖對象events屬性或者jQuery.on()方法注冊:
? ?- 使用events屬性注冊的事件嘶朱,回調(diào)函數(shù)的this指向視圖對象
? ?- 使用jQuery注冊事件光酣,回調(diào)函數(shù)this指向DOM元素
- Event API
? ?使用Event API注冊事件也有兩種情況:
? ?- 使用on()方法注冊事件,上下文默認(rèn)是指向當(dāng)前對象财异,也可以通過第三個參數(shù)傳入作為回調(diào)函數(shù)上下文
? ?- 使用listenTo()注冊事件唱遭,回調(diào)函數(shù)this指向當(dāng)前對象