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判断IE6/IE7/FF的代码[XMLHttpRequest]
Feb 16 Javascript
JavaScript使用HTML5的window.postMessage实现跨域通信例子
Apr 11 Javascript
window.onload与$(document).ready()的区别分析
May 30 Javascript
xmlplus组件设计系列之树(Tree)(9)
May 02 Javascript
lhgcalendar时间插件限制只能选择三个月的实现方法
Jul 03 Javascript
JS获取当前地理位置的方法
Oct 25 Javascript
Bootstrap 树控件使用经验分享(图文解说)
Nov 06 Javascript
浅谈Fetch 数据交互方式
Dec 20 Javascript
js纯前端实现腾讯cos文件上传功能的示例代码
May 14 Javascript
vue视图不更新情况详解
May 16 Javascript
JS实现压缩上传图片base64长度功能
Dec 03 Javascript
Vue CLI4 Vue.config.js标准配置(最全注释)
Jun 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
解决MySQL中文输出变成问号的问题
2008/06/05 PHP
PHP IF ELSE简化/三元一次式的使用
2011/08/22 PHP
php无限级分类实现方法分析
2016/10/19 PHP
javascript与CSS复习(三)
2010/06/29 Javascript
jQuery EasyUI API 中文文档 - ValidateBox验证框
2011/10/06 Javascript
JavaScript的常见兼容问题及相关解决方法(chrome/IE/firefox)
2013/12/31 Javascript
jQuery层动画定位滑动效果的方法
2015/04/30 Javascript
在Javascript中处理数组之toSource()方法的使用
2015/06/09 Javascript
Jquery中使用show()与hide()方法动画显示和隐藏图片
2015/10/08 Javascript
Bootstrap零基础学习第一课之模板
2016/07/18 Javascript
Vuejs第十一篇组件之slot内容分发实例详解
2016/09/09 Javascript
让html元素随浏览器的大小自适应垂直居中的实现方法
2016/10/12 Javascript
JS中闭包的经典用法小结(2则示例)
2016/12/28 Javascript
Bootstrap实现基于carousel.js框架的轮播图效果
2017/05/02 Javascript
JavaScript中Object值合并方法详解
2017/12/22 Javascript
深入理解 webpack 文件打包机制(小结)
2018/01/08 Javascript
更改BootStrap popover的默认样式及popover简单用法
2018/09/13 Javascript
vue-cli项目代理proxyTable配置exclude的方法
2018/09/20 Javascript
tracking.js页面人脸识别插件使用方法
2020/04/16 Javascript
Python中的作用域规则详解
2015/01/30 Python
Python中暂存上传图片的方法
2015/02/18 Python
使用Python对IP进行转换的一些操作技巧小结
2015/11/09 Python
python实现Excel文件转换为TXT文件
2019/04/28 Python
对python特殊函数 __call__()的使用详解
2019/07/02 Python
Pytorch中Tensor与各种图像格式的相互转化详解
2019/12/26 Python
利用python实现凯撒密码加解密功能
2020/03/31 Python
Ubuntu中配置TensorFlow使用环境的方法
2020/04/21 Python
公认8个效率最高的爬虫框架
2020/07/28 Python
世界最大域名注册商:GoDaddy
2016/07/24 全球购物
英国门把手公司:Door Handle Company
2019/05/12 全球购物
Diptyque英国官方网站:源自法国的知名香氛品牌
2019/08/28 全球购物
莫斯科珠宝厂官方网站:Miuz
2020/09/19 全球购物
总经理司机职责
2014/02/02 职场文书
《我的第一本书》教学反思
2014/02/15 职场文书
大学生社团活动总结
2014/04/26 职场文书
详细聊聊MySQL中慢SQL优化的方向
2021/08/30 MySQL