用javascript試作decorator

 Mon, 30 Apr 2007 10:56:19 +0800

decorator在動態地賦予權責上相當好用,所以想試試看用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);

這樣就只有在滑鼠移入移出會改變背景顏色。

有圖有真相:http://www.fillano.idv.tw/test48.html