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 相关文章推荐
[原创]静态页面也可以实现预览 列表不同的显示方式
Oct 14 Javascript
动态加载图片路径 保持JavaScript控件的相对独立性
Sep 03 Javascript
Javascript实现关联数据(Linked Data)查询及注意细节
Feb 22 Javascript
js中的getAttribute方法使用示例
Aug 01 Javascript
JavaScript异步加载浅析
Dec 28 Javascript
JavaScript中的console.trace()函数介绍
Dec 29 Javascript
JavaScript多图片上传案例
Sep 28 Javascript
Jquery实现的简单轮播效果【附实例】
Apr 19 Javascript
JS实现带导航城市列表以及输入搜索功能
Jan 04 Javascript
Vue单页面应用保证F5强刷不清空数据的解决方案
Jan 31 Javascript
原生JS封装_new函数实现new关键字的功能
Aug 12 Javascript
浅谈JavaScript作用域
Dec 06 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
ajax+php打造进度条 readyState各状态
2010/03/20 PHP
简单实用的PHP防注入类实例
2014/12/05 PHP
php数组键名技巧小结
2015/02/17 PHP
[原创]php逐行读取txt文件写入数组的方法
2015/07/02 PHP
PHP树-不需要递归的实现方法
2016/06/21 PHP
php遍历替换目录下文件指定内容的方法
2016/11/10 PHP
php中bind_param()函数用法分析
2017/03/28 PHP
详解PHP处理字符串类似indexof的方法函数
2017/06/11 PHP
提高Laravel应用性能方法详解
2019/06/24 PHP
Yii框架模拟组件调用注入示例
2019/11/11 PHP
详细分析PHP 命名空间(namespace)
2020/06/30 PHP
Jquery下判断Id是否存在的代码
2011/01/06 Javascript
如何通过javascript操作web控件的自定义属性
2013/11/25 Javascript
js中opener与parent的区别详细解析
2014/01/14 Javascript
javascript实现网页背景烟花效果的方法
2015/08/06 Javascript
jQuery fancybox在ie浏览器下无法显示关闭按钮的解决办法
2016/02/19 Javascript
浅析jQuery Ajax请求参数和返回数据的处理
2016/02/24 Javascript
javascript中this关键字详解
2016/12/12 Javascript
AngularJS定时器的使用与移除操作方法【interval与timeout】
2016/12/14 Javascript
AngularJS Select(选择框)使用详解
2017/01/18 Javascript
VUE多层路由嵌套实现代码
2017/05/15 Javascript
深入理解Vue生命周期、手动挂载及挂载子组件
2017/09/27 Javascript
vue router嵌套路由在history模式下刷新无法渲染页面问题的解决方法
2018/01/25 Javascript
angularjs中$http异步上传Excel文件方法
2018/02/23 Javascript
vue.js循环radio的实例
2019/11/07 Javascript
JavaScript检测是否开启了控制台(F12调试工具)
2020/10/02 Javascript
讲解Python中for循环下的索引变量的作用域
2015/04/15 Python
Python的Flask框架中实现简单的登录功能的教程
2015/04/20 Python
Python聊天室实例程序分享
2016/01/05 Python
Python调用SQLPlus来操作和解析Oracle数据库的方法
2016/04/09 Python
pycharm导入源码的具体步骤
2020/08/04 Python
李维斯德国官方网上商店:Levi’s德国
2016/09/10 全球购物
个人收入证明范本
2014/09/18 职场文书
公司合并协议书范本
2014/09/30 职场文书
初中生入团申请书范文(五篇)
2019/10/16 职场文书
「约定的梦幻岛」作画发布诺曼生日新绘
2022/03/21 日漫