欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

JavaScript Timer实现代码

程序员文章站 2022-03-23 13:32:41
ok,不废话了,实现一个javascript的timer吧 比起as3的timer类,功能上略有改动 timer2.src.js 复制代码 代码如下: /** * time...
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,明天换了。你又要从头开始了。