用javascript試作decorator
Mon, 30 Apr 2007 10:56:19 +0800decorator在動態地賦予權責上相當好用,所以想試試看用javascript可不可以做出來類似的效果:)
嘗試的目標:可以用new運算子建立各物件的權責關係,然後用共同的的方法(各物件實作上有不一樣,但是有一致的傳入參數)很簡單就可以達成效果。
試作的功能:依照事件改變物件屬性。
接著就開始了:
var DownEventAttacher = function (obj) { this._obj = obj; this.setEvent = function (func, dom) { dom.onmousedown = func; if (typeof this._obj == "object") { this._obj.setEvent(func, dom); } } } var UpEventAttacher = function (obj) { this._obj = obj; this.setEvent = function (func, dom) { dom.onmouseup = func; if (typeof this._obj == "object") { this._obj.setEvent(func, dom); } } } var OutEventAttacher = function (obj) { this._obj = obj; this.setEvent = function (func, dom) { dom.onmouseout = func; if (typeof this._obj == "object") { this._obj.setEvent(func, dom); } } } var OverEventAttacher = function (obj) { this._obj = obj; this.setEvent = function (func, dom) { dom.onmouseover = func; if (typeof this._obj == "object") { this._obj.setEvent(func, dom); } } }
關鍵在於,函數的constructor會把傳入的參數存起來(這會是一個new出來的物件),然後在呼叫方法時除了自己本身要處理的code以外,還呼叫了傳入物件的同一個方法。
接著設計要測試的效果。我想處理div的背景會容易看到效果,所以設計了一個函數:
function testf (e) { if (e) { //firefox或mozilla處理事件的方法 switch (e.type) { case "mouseover": e.target.style.backgroundColor = "green"; break; case "mouseout": e.target.style.backgroundColor = "yellow"; break; case "mousedown": e.target.style.backgroundColor = "black"; break; case "mouseup": e.target.style.backgroundColor = "green"; break; } } else { //ie處理事件的方法,目前只試了ie7 switch (event.type) { case "mouseover": event.srcElement.style.backgroundColor = "green"; break; case "mouseout": event.srcElement.style.backgroundColor = "yellow"; break; case "mousedown": event.srcElement.style.backgroundColor = "black"; break; case "mouseup": event.srcElement.style.backgroundColor = "green"; break; } } }
使用的時候,只要一連串地把需要加入權責的事件對應的再constructor加進來就可以。例如以下的例子是在一個div block上達成效果,div的id是test,背景顏色是yellow:
var test = document.getElementById("test"); var attacher = new OverEventAttacher( new OutEventAttacher( new DownEventAttacher( new UpEventAttacher() ))); attacher.setEvent(testf, test);
這樣在滑鼠移入、移出、click都會有改變背景顏色的效果。
如果不需要在mousedown/mouseup事件讓div block改變背景顏色,只要調整一下:
var test = document.getElementById("test"); var attacher = new OverEventAttacher( new OutEventAttacher() ); attacher.setEvent(testf, test);
這樣就只有在滑鼠移入移出會改變背景顏色。