一個JavaScript的timer的代碼
比起as3的Timer類,功能上略有改動
複製代碼 代碼如下:
/**
* Timer 模型
*
* @author rainsilence
* @version 2.0
*/
(function() {
/**
* TimerEvent constructor 構造器
*
* @param type 事件類型
* @param bubbles 是否毛票
* @param cancelable 是否可取消
*/
TimerEvent = function(type, bubbles, cancelable) {
= type;
les = bubbles;
elable = cancelable;
};
/**
* Event 時間事件聲明
*
* @event TIMER
* @event TIMER_COMPLETE
*/
extend(TimerEvent, {
TIMER : "timer",
TIMER_COMPLETE : "timerComplete"
});
/**
* Event 方法
*
* @method toString
*/
extend(otype, {
toString : function() {
return "[TimerEvent type=" + +
" bubbles=" + les +
" cancelable=" + elable +"]";
}
});
/**
* Extend 擴展類,對象的屬性或者方法
*
* @param target 目標對象
* @param methods 這裏改成param也許更合適,表示承載着對象,方法的對象,用於target的擴展
*/
function extend(target, methods) {
if (!target) {
target = {};
}
for (var prop in methods) {
target[prop] = methods[prop];
}
return target;
}
/**
* Timer 構造器
*
* @param delay 延時多少時間執行方法句柄
* @param repeatCount 重複多少次,如果不設置,代表重複無限次
*/
Timer = function(delay, repeatCount) {
var listenerMap = {};
listenerMap[R] = [];
listenerMap[R_COMPLETE] = [];
extend(this, {
currentCount : 0,
running : false,
delay : delay,
repeatCount : repeatCount,
// true:Interval,false:Timeout
repeatType : repeatCount == null || repeatCount < 1 ? true : false,
handler : listenerMap,
timerId : 0,
isCompleted : false
});
};
// 事件對象初始化(這部分未實現)
var timerEvent = new TimerEvent(R, false, false);
var timerCompleteEvent = new TimerEvent(R_COMPLETE, false, false);
/**
* Timer 計時器方法
*
* @method addEventListener 增加一個方法句柄(前兩個參數必須,後一個參數可選)
* @method removeEventListener 移除一個方法句柄
* @method start 開始計時器
* @method stop 結束計時器
* @method reset 重置計時器
*/
extend(otype, {
addEventListener : function(type, listener, useCapture) {
if (type == R || type == R_COMPLETE) {
if (!listener) {
alert("Listener is null");
}
if (useCapture == true) {
ler[type]ce(0, 0, [listener]);
} else {
ler[type](listener);
}
}
},
removeEventListener : function(type, listener) {
if (type == R || type == R_COMPLETE) {
if (!listener) {
ler[type] = [];
} else {
var listeners = ler[type];
for (var index = 0; index < th; index++) {
if (listeners[index] == listener) {
ce(index, 1);
break;
}
}
}
}
},
start : function() {
var timerThis = this;
if (ing == true || mpleted) {
return;
}
if (ler[R]th == 0 &&
ler[R_COMPLETE]th == 0) {
alert("No Function");
return;
}
if (atType) {
rId = setInterval(function() {
dispachListener(ler[R], timerEvent);
entCount++;
}, y);
} else {
rId = setTimeout(function() {delayExecute(ler[R]);}, y);
}
ing = true;
function delayExecute(listeners) {
dispachListener(listeners, timerEvent);
entCount++;
if (entCount < atCount) {
if (ing) {
rId = setTimeout(function() {delayExecute(listeners);}, y);
}
} else {
ing = false;
}
if (ing == false) {
if (!mpleted) {
dispachListener(ler[R_COMPLETE], timerCompleteEvent);
}
mpleted = true;
}
}
function dispachListener(listeners, event) {
for (var prop in listeners) {
listeners[prop](event);
}
}
},
stop : function() {
ing = false;
if (rId == null) {
return;
}
if (atType) {
clearInterval(rId);
} else {
clearTimeout(rId);
}
if (!mpleted) {
var listeners = ler[R_COMPLETE];
for (var prop in listeners) {
listeners[prop](timerCompleteEvent);
}
}
mpleted = true;
},
reset : function() {
entCount = 0;
mpleted = false;
}
});
})();
接下來測試吧,大家見過新浪網上的滾動顯示嗎?用setTimeout寫的,真叫牛叉。。。。。。換成Timer重構,簡單易懂
複製代碼 代碼如下:
ine {
width: 400px;
height: 80px;
border-bottom-style: solid;
border-width: 1px;
}
ist {
border-style: solid;
border-width: 1px;
width:400px;
height: 80px;
overflow: hidden;
}
1
2
3
4
addEventListener的`useCapture參數本為捕獲階段觸發之意,現在改成如果true,則在其他句柄之前觸發,如果false,則在其他句柄之後觸發。
後記:
現在貌似大家比較流行評論説明書的用法。。。比如struts+spring+hibernate。而忽略了編程的實質。希望大家多看源碼,多討論源碼,那樣才會有所謂的思想。否則人家今天用這個framework,明天換了。你又要從頭開始了。