JavaScript Timer实现代码


Posted in Javascript onFebruary 17, 2010

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,明天换了。你又要从头开始了。
Javascript 相关文章推荐
Js 本页面传值实现代码
May 17 Javascript
判断浏览器的javascript版本的代码
Sep 03 Javascript
js对象数组按属性快速排序
Jan 31 Javascript
图解js图片轮播效果
Dec 20 Javascript
JavaScript reduce和reduceRight详解
Oct 24 Javascript
详解使用webpack构建多页面应用
Dec 21 Javascript
element-ui表格列金额显示两位小数的方法
Aug 24 Javascript
JS/jQuery实现获取时间的方法及常用类完整示例
Mar 07 jQuery
vue图片加载失败时用默认图片替换的方法
Aug 29 Javascript
layui使用button按钮 点击出现弹层 弹层中加载表单的实例
Sep 04 Javascript
JavaScript进阶(三)闭包原理与用法详解
May 09 Javascript
JavaScript事件概念详解(区分静态注册和动态注册)
Feb 05 Javascript
两个比较有用的Javascript工具函数代码
Feb 17 #Javascript
类似GMAIL的Ajax信息反馈显示
Feb 16 #Javascript
JavaScript 10件让人费解的事情
Feb 15 #Javascript
JQuery 动画卷页 返回顶部 动画特效(兼容Chrome)
Feb 15 #Javascript
jQuery 处理表单元素的代码
Feb 15 #Javascript
jQuery 树形结构的选择器
Feb 15 #Javascript
jQuery 处理网页内容的实现代码
Feb 15 #Javascript
You might like
晶体管来复再生式二管收音机
2021/03/02 无线电
PHP中使用sleep造成mysql读取失败的案例和解决方法
2014/08/21 PHP
PHP Reflection API详解
2015/05/12 PHP
php实现统计目录文件大小的函数
2015/12/25 PHP
php实现通过stomp协议连接ActiveMQ操作示例
2020/02/23 PHP
Thinkphp 框架配置操作之配置加载与读取配置实例分析
2020/05/15 PHP
修改js Calendar日历控件 兼容IE9/谷歌/火狐
2013/01/04 Javascript
网页右下角弹出窗体实现代码
2014/06/05 Javascript
jquery+javascript编写国籍控件
2015/02/12 Javascript
JQuery控制radio选中和不选中方法总结
2015/04/15 Javascript
JavaScript入门基础
2015/08/12 Javascript
jquery中validate与form插件提交的方式小结
2016/03/26 Javascript
详解jQuery lazyload 懒加载
2016/12/19 Javascript
vuejs事件中心管理组件间的通信详解
2017/08/09 Javascript
解析vue中的$mount
2017/12/21 Javascript
JS实现容器模块左右拖动效果
2020/01/14 Javascript
小程序实现图片移动缩放效果
2020/05/26 Javascript
vue使用element-ui实现表单验证
2020/12/13 Vue.js
kNN算法python实现和简单数字识别的方法
2014/11/18 Python
python实现在每个独立进程中运行一个函数的方法
2015/04/23 Python
python中lambda与def用法对比实例分析
2015/04/30 Python
Python使用matplotlib实现在坐标系中画一个矩形的方法
2015/05/20 Python
python开发简易版在线音乐播放器
2017/03/03 Python
Python实现读写sqlite3数据库并将统计数据写入Excel的方法示例
2017/08/07 Python
Python Logging 日志记录入门学习
2018/06/02 Python
详解HTML5 Canvas标签及基本使用
2020/01/10 HTML / CSS
澳大利亚婴儿礼品公司:The Baby Gift Company
2018/11/04 全球购物
美国Curacao百货连锁店网站:iCuracao.com
2019/07/20 全球购物
Pamela Love官网:纽约设计师Pamela Love的精美、时尚和穿孔珠宝
2020/10/19 全球购物
主题婚礼策划方案
2014/02/10 职场文书
《花的勇气》教后反思
2014/02/12 职场文书
餐饮周年庆活动方案
2014/08/14 职场文书
解除劳动合同协议书范本
2014/09/13 职场文书
2015年幼师个人工作总结
2015/10/15 职场文书
Mysql 性能监控及调优
2021/04/06 MySQL
Python编解码问题及文本文件处理方法详解
2021/06/20 Python