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 escape,unescape解决中文乱码问题的方法
May 26 Javascript
JS代码同步文本框内容的实例方法
Jul 12 Javascript
JS实现仿中关村论坛评分后弹出提示效果的方法
Feb 23 Javascript
jQuery+Ajax+PHP弹出层异步登录效果(附源码下载)
May 27 Javascript
JS JSOP跨域请求实例详解
Jul 04 Javascript
js判断手机号是否正确并返回的实现代码
Jan 17 Javascript
基于JavaScript实现的折半查找算法示例
Apr 14 Javascript
Vue隐藏显示、只读实例代码
Jul 18 Javascript
JS实现骰子3D旋转效果
Oct 24 Javascript
ant-design-vue中的select选择器,对输入值的进行筛选操作
Oct 24 Javascript
react-native 实现购物车滑动删除效果的示例代码
Jan 15 Javascript
js中Object.create实例用法详解
Oct 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
PHP 基于文件头的文件类型验证类函数
2012/05/01 PHP
php实现可运算的验证码
2015/11/10 PHP
PHP基于phpqrcode类生成二维码的方法详解
2018/03/14 PHP
Laravel 模型使用软删除-左连接查询-表起别名示例
2019/10/24 PHP
ASP中用Join和Array,可以加快字符连接速度的代码
2007/08/22 Javascript
JS应用之禁止抓屏、复制、打印
2008/02/21 Javascript
离开页面时检测表单元素是否被修改,提示保存的js代码
2010/08/25 Javascript
web开发人员学习jQuery的6大理由及jQuery的优势介绍
2013/01/03 Javascript
Js 导出table内容到Excel的简单实例
2013/11/19 Javascript
JavaScript把数组作为堆栈使用的方法
2015/03/20 Javascript
解决JS请求服务器gbk文件乱码的问题
2015/10/16 Javascript
基于jquery实现ajax无刷新评论
2020/08/19 Javascript
关于动态生成dom绑定事件失效的原因及解决方法
2016/08/06 Javascript
ion content 滚动到底部会遮住一部分视图的快速解决方法
2016/09/06 Javascript
使用JavaScript触发过渡效果的方法
2017/01/19 Javascript
Extjs gridpanel 中的checkbox(复选框)根据某行的条件不能选中的解决方法
2017/02/17 Javascript
Vue项目从webpack3.x升级webpack4不完全指南
2019/04/28 Javascript
JS字符串与二进制的相互转化实例代码详解
2019/06/28 Javascript
js获取 gif 的帧数的代码实例
2019/09/10 Javascript
微信内置开发 iOS修改键盘换行为搜索的解决方案
2019/11/06 Javascript
jQuery实现推拉门效果
2020/10/19 jQuery
[06:16]第十四期-国士无双绝地翻盘之撼地神牛
2014/06/24 DOTA
Python中的defaultdict模块和namedtuple模块的简单入门指南
2015/04/01 Python
python操作ie登陆土豆网的方法
2015/05/09 Python
python2.7 mayavi 安装图文教程(推荐)
2017/06/22 Python
解决Python 中英文混输格式对齐的问题
2018/07/16 Python
详解python tkinter教程-事件绑定
2019/03/28 Python
Python控制鼠标键盘代码实例
2020/12/08 Python
CSS3制作苹果风格键盘特效
2015/02/26 HTML / CSS
日本钓鱼渔具和户外用品网上商店:naturum
2016/08/07 全球购物
公司行政经理岗位职责
2013/12/24 职场文书
新法人代表任命书
2014/06/06 职场文书
会议欢迎词范文
2015/01/27 职场文书
导游词之襄阳古城
2019/09/27 职场文书
使用python求解迷宫问题的三种实现方法
2022/03/17 Python
《艾尔登法环》1.03.3补丁上线 碎星伤害调整
2022/04/06 其他游戏