当前位置: 首页 > 图文教程 > 网络编程 > Javascript > JavaScript Timer实现代码

Javascript
JS option location 页面跳转实现代码
ExtJS 简介 让你知道extjs是什么
ExtJs 学习笔记 Hello World!
ExtJs 学习笔记基础篇 Ext组件的使用
ExtJs 学习笔记 Ext.Panle Ext.TabPanel Ext.Viewport
漂亮的脚本日历,和大家分享
JS Tween 颜色渐变
js 图片轮播(5张图片)
开发跨浏览器javascript常见注意事项
通用JS事件写法实现代码
Js 订制自己的AlertBox(信息提示框)
js 浮动层菜单收藏
JavaScript入门教程(10) 认识其他对象
JQuery 常用方法基础教程
jQuery 页面载入进度条实现代码
jQuery Ajax 全解析
CSS+Table图文混排中实现文本自适应图片宽度(超简单+跨所有浏览器)
Ext JS Grid在IE6 下宽度的问题解决方法
js window.event对象详尽解析
JavaScript 悬浮窗口实现代码

Javascript 中的 JavaScript Timer实现代码


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2010-02-27   浏览: 152 ::
收藏到网摘: n/a

最近开始接触flex,比起javascript,感觉as3的Timer类甚是强大。而javascript只有裸体的setTimeout,setInternval。要实现稍微复杂一点的功能,稍微没有底子的程序员就会把代码写的很乱。 ok,不废话了,实现一个javascript的Timer吧
比起as3的Timer类,功能上略有改动
timer2.src.js
复制代码 代码如下:

/**
* Timer 模型
*
* @author rainsilence
* @version 2.0
*/
(function() {
/**
* TimerEvent constructor 构造器
*
* @param type 事件类型
* @param bubbles 是否毛票
* @param cancelable 是否可取消
*/
TimerEvent = function(type, bubbles, cancelable) {
this.type = type;
this.bubbles = bubbles;
this.cancelable = cancelable;
};
/**
* Event 时间事件声明
*
* @event TIMER
* @event TIMER_COMPLETE
*/
extend(TimerEvent, {
TIMER : "timer",
TIMER_COMPLETE : "timerComplete"
});
/**
* Event 方法
*
* @method toString
*/
extend(TimerEvent.prototype, {
toString : function() {
return "[TimerEvent type=" + this.type +
" bubbles=" + this.bubbles +
" cancelable=" + this.cancelable +"]";
}
});
/**
* 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[TimerEvent.TIMER] = [];
listenerMap[TimerEvent.TIMER_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(TimerEvent.TIMER, false, false);
var timerCompleteEvent = new TimerEvent(TimerEvent.TIMER_COMPLETE, false, false);
/**
* Timer 计时器方法
*
* @method addEventListener 增加一个方法句柄(前两个参数必须,后一个参数可选)
* @method removeEventListener 移除一个方法句柄
* @method start 开始计时器
* @method stop 结束计时器
* @method reset 重置计时器
*/
extend(Timer.prototype, {
addEventListener : function(type, listener, useCapture) {
if (type == TimerEvent.TIMER || type == TimerEvent.TIMER_COMPLETE) {
if (!listener) {
alert("Listener is null");
}
if (useCapture == true) {
this.handler[type].splice(0, 0, [listener]);
} else {
this.handler[type].push(listener);
}
}
},
removeEventListener : function(type, listener) {
if (type == TimerEvent.TIMER || type == TimerEvent.TIMER_COMPLETE) {
if (!listener) {
this.handler[type] = [];
} else {
var listeners = this.handler[type];
for (var index = 0; index < listeners.length; index++) {
if (listeners[index] == listener) {
listeners.splice(index, 1);
break;
}
}
}
}
},
start : function() {
var timerThis = this;
if (this.running == true || this.isCompleted) {
return;
}
if (this.handler[TimerEvent.TIMER].length == 0 &&
this.handler[TimerEvent.TIMER_COMPLETE].length == 0) {
alert("No Function");
return;
}
if (this.repeatType) {
this.timerId = setInterval(function() {
dispachListener(timerThis.handler[TimerEvent.TIMER], timerEvent);
timerThis.currentCount++;
}, this.delay);
} else {
this.timerId = setTimeout(function() {delayExecute(timerThis.handler[TimerEvent.TIMER]);}, this.delay);
}
this.running = true;
function delayExecute(listeners) {
dispachListener(listeners, timerEvent);
timerThis.currentCount++;
if (timerThis.currentCount < timerThis.repeatCount) {
if (timerThis.running) {
timerThis.timerId = setTimeout(function() {delayExecute(listeners);}, timerThis.delay);
}
} else {
timerThis.running = false;
}
if (timerThis.running == false) {
if (!timerThis.isCompleted) {
dispachListener(timerThis.handler[TimerEvent.TIMER_COMPLETE], timerCompleteEvent);
}
timerThis.isCompleted = true;
}
}
function dispachListener(listeners, event) {
for (var prop in listeners) {
listeners[prop](event);
}
}
},
stop : function() {
this.running = false;
if (this.timerId == null) {
return;
}
if (this.repeatType) {
clearInterval(this.timerId);
} else {
clearTimeout(this.timerId);
}
if (!this.isCompleted) {
var listeners = this.handler[TimerEvent.TIMER_COMPLETE];
for (var prop in listeners) {
listeners[prop](timerCompleteEvent);
}
}
this.isCompleted = true;
},
reset : function() {
this.currentCount = 0;
this.isCompleted = false;
}
});
})();

接下来测试吧,大家见过新浪网上的滚动显示吗?用setTimeout写的,真叫牛叉。。。。。。换成Timer重构,简单易懂
timerTest.html
复制代码 代码如下:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-31j">
<title>Insert title here</title>
<style type="text/css">
.rowLine {
width: 400px;
height: 80px;
border-bottom-style: solid;
border-width: 1px;
}
.barList {
border-style: solid;
border-width: 1px;
width:400px;
height: 80px;
overflow: hidden;
}
</style>
<script type="text/javascript" src="js/timer2.src.js"></script>
<script type="text/javascript">
<!--
var timer = new Timer(50);
var globalTimer = new Timer(10000);
var bList;
function init() {
bList = document.getElementById("barList");
timer.addEventListener(TimerEvent.TIMER, calTime);
timer.start();
globalTimer.addEventListener(TimerEvent.TIMER, controlTime);
globalTimer.start();
}
function controlTime() {
if (!timer.running) {
timer.reset();
timer.start();
}
}
function calTime() {
bList.scrollTop += 1;
if (bList.scrollTop > 80) {
timer.stop();
var barNode = bList.firstChild;
if (barNode.nodeType == 3) {
bList.appendChild(barNode);
bList.appendChild(bList.getElementsByTagName("div")[0]);
} else {
bList.appendChild(barNode);
}
bList.scrollTop = 0;
}
}
window.onload = init;
// -->
</script>
</head>
<body>
<div class="barList" id="barList">
<div class="rowLine" style="background-color: red" style="background-color: red">1</div>
<div class="rowLine" style="background-color: pink" style="background-color: pink">2</div>
<div class="rowLine" style="background-color: blue" style="background-color: blue">3</div>
<div class="rowLine" style="background-color: gray" style="background-color: gray">4</div>
</div>
</body>
</html>

addEventListener的useCapture参数本为捕获阶段触发之意,现在改成如果true,则在其他句柄之前触发,如果false,则在其他句柄之后触发。
后记:
现在貌似大家比较流行评论说明书的用法。。。比如struts+spring+hibernate。而忽略了编程的实质。希望大家多看源码,多讨论源码,那样才会有所谓的思想。否则人家今天用这个framework,明天换了。你又要从头开始了。