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 相关文章推荐
HTML TO JavaScript 转换
Jun 26 Javascript
学习ExtJS accordion布局
Oct 08 Javascript
jQuery在html有效在jsp无效的原因及解决方法
Aug 02 Javascript
前端js文件合并的三种方式推荐
May 19 Javascript
基于jQuery实现的查看全文功能【实用】
Dec 11 Javascript
angular中不同的组件间传值与通信的方法
Nov 04 Javascript
vue-cli3 从搭建到优化的详细步骤
Jan 20 Javascript
浅谈发布订阅模式与观察者模式
Apr 09 Javascript
Vue使用Canvas绘制图片、矩形、线条、文字,下载图片
Apr 26 Javascript
在vue中动态添加class类进行显示隐藏实例
Nov 09 Javascript
layui table表格数据的新增,修改,删除,查询,双击获取行数据方式
Nov 14 Javascript
JavaScript事件冒泡机制原理实例解析
Jan 14 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
PHP详细彻底学习Smarty
2008/03/27 PHP
php中++i 与 i++ 的区别
2012/08/08 PHP
PHP+Mysql树型结构(无限分类)数据库设计的2种方式实例
2014/07/15 PHP
浅析PHP文件下载原理
2014/12/25 PHP
php根据某字段对多维数组进行排序的方法
2015/03/07 PHP
JavaScript的Number对象的toString()方法
2015/12/18 Javascript
Angular ng-repeat 对象和数组遍历实例
2016/09/14 Javascript
vue-router路由参数刷新消失的问题解决方法
2017/06/17 Javascript
详解vue模拟加载更多功能(数据追加)
2017/06/23 Javascript
微信小程序出现wx.navigateTo页面不跳转问题的解决方法
2017/12/26 Javascript
echarts鼠标覆盖高亮显示节点及关系名称详解
2018/03/17 Javascript
详解vue组件基础
2018/05/04 Javascript
react antd表格中渲染一张或多张图片的实例
2020/10/28 Javascript
[00:32]2018DOTA2亚洲邀请赛Liquid出场
2018/04/03 DOTA
[19:54]夜魇凡尔赛茶话会 第一期02:看图识人
2021/03/11 DOTA
Python的Flask框架中实现分页功能的教程
2015/04/20 Python
Django自定义分页与bootstrap分页结合
2021/02/22 Python
利用python模拟实现POST请求提交图片的方法
2017/07/25 Python
Python探索之爬取电商售卖信息代码示例
2017/10/27 Python
python删除过期log文件操作实例解析
2018/01/31 Python
tensorflow TFRecords文件的生成和读取的方法
2018/02/06 Python
Python计算库numpy进行方差/标准方差/样本标准方差/协方差的计算
2018/12/28 Python
python安装scipy的方法步骤
2019/06/26 Python
对python3 sort sorted 函数的应用详解
2019/06/27 Python
Django 迁移、操作数据库的方法
2019/08/02 Python
Selenium常见异常解析及解决方案示范
2020/04/10 Python
美国大尺码女装零售商:TORRID
2016/10/01 全球购物
Skyscanner阿联酋:全球领先的旅游搜索平台
2017/11/25 全球购物
戴尔美国官方折扣店:Dell Outlet
2018/02/13 全球购物
贸易跟单员英文求职信
2014/04/19 职场文书
移交协议书
2014/08/19 职场文书
2014年学习委员工作总结
2014/11/14 职场文书
2014年药品销售工作总结
2014/12/16 职场文书
基于Nginx实现限制某IP短时间访问次数
2021/03/31 Servers
Go语言基础知识点介绍
2021/07/04 Golang
Vue操作Storage本地化存储
2022/04/29 Vue.js