事件是一種叫作觀察者的設計模式,這是一種建立鬆散耦合的技術。觀察者模式由兩類對象組成:主體和觀察者。主體負責發佈事件。同時觀察者經過訂閱這些事件來觀察該主體。該模式的一個關鍵概念是主體並不知道觀察者的任何事情,也就是說它能夠獨自存在並正常運做即便觀察者不存在。從另外一方面來講。觀察者知道主體並能註冊事件的回調函數(事件處理程序),涉及到Dom上時,Dom元素即是主體,你的事件處理代碼即是觀察者。javascript
事件是與Dom交互的最多見的方式,但它們也能夠用於非Dom代碼中--經過實現自定義事件。java
自定義事件背後的概念是建立一個管理事件的對象。讓其餘對象監聽那些事件。實現此功能的基本模式能夠定義以下:設計模式
function EventTarget(name1) { this.name = name1; this.handlers = {} } EventTarget.prototype = { constructor: EventTarget, addHandler: function(type, handler) { console.log(type); //剛開始只有type並無爲this.handlers[type]賦值 if (typeof this.handlers[type] == "undefined") { this.handlers[type] = []; console.log("hi") } //接着執行push this.handlers[type].push(handler); console.log(this.handlers[type]); }, fire: function(event) { if (!event.target) { event.target = this; console.log("not have eventTarget") } if (this.handlers[event.type] instanceof Array) { console.log("isArray") var handlers = this.handlers[event.type]; //循環執行多個事件 for (var i = 0, len = handlers.length; i < len; i++) { handlers[i](event); } } }, removeHandler: function(type, handler) { if (this.handlers[type] instanceof Array) { var handlers = this.handlers[type]; for (var i = 0, len = handlers.length; i < len; i++) { if (handlers[i] === handler) { break; } } handlers.splice(i, 1); } console.log(handlers); } }
而後使用EventTarget類型的自定義事件:函數
function handleMessage(event) { alert("Message received:" + event.message); } //建立一個新對象 var target = new EventTarget() //添加一個事件處理程序 target.addHandler("message",handleMessage) //觸發事件 target.fire({type:"message",message:"Hello World"}) //刪除事件處理程序 target.removeHandler("message",handleMessage); //觸發事件不會執行 target.fire({type:"message",message:"Hello Worldmmm"})
在這段代碼中,定義了handleMessage()函數用於處理message事件。它接受event對象並輸出message屬性。調用target對象的addHandler()方法並傳給"message"以及hadleMessage()函數。在接下來的一行,調用了fire()函數,並傳給了2個屬性,即type和message的對象。而後刪除了事件處理程序,這樣即便事件再次出發,也不會顯示任何警告框。this
由於這種功能是封裝在一種自定義類型中的,其它對象能夠繼承EventTarget並得到這個行爲prototype
function Person(name) { this.name = name; this.etarget = new EventTarget(this.name) } Person.prototype = { constructor: Person, addMessage: function(type, fn) { this.etarget.addHandler(type, fn) }, say: function(message) { this.etarget.fire({ type: "message", message: message }) console.log(this.name) } } function handleMessage(event) { console.log(event) //彈出NICHOLAS--SAYS:hi there alert(event.target.name + "---says:" + event.message); } //建立新Person實例 var person = new Person("NICHOLAS"); person.addMessage("message", handleMessage); person.say("hi there")