前言:最近开始接触flex,比起javascript,感觉as3的Timer类甚是强大。而javascript只有裸体的setTimeout,setInternval。要实现稍微复杂一点的功能,稍微没有底子的程序员就会把代码写的很乱。
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" mce_style="background-color: red">1</div>
<div class="rowLine" style="background-color: pink" mce_style="background-color: pink">2</div>
<div class="rowLine" style="background-color: blue" mce_style="background-color: blue">3</div>
<div class="rowLine" style="background-color: gray" mce_style="background-color: gray">4</div>
</div>
</body>
</html>
addEventListener的useCapture参数本为捕获阶段触发之意,现在改成如果true,则在其他句柄之前触发,如果false,则在其他句柄之后触发。
后记:
现在貌似大家比较流行评论说明书的用法。。。比如struts+spring+hibernate。而忽略了编程的实质。希望大家多看源码,多讨论源码,那样才会有所谓的思想。否则人家今天用这个framework,明天换了。你又要从头开始了。
分享到:
相关推荐
### 原生JavaScript实现图片轮播功能 #### 背景介绍 本文档主要介绍了如何使用原生JavaScript实现一个图片轮播的功能。这个轮播功能不仅能够满足基本的自动循环播放图片的需求,还能实现通过点击左右箭头来手动切换...
综上所述,`ajax_timer`是利用AJAX和JavaScript定时器功能实现的,用于周期性地向服务器发送请求,获取更新数据并展示在网页上。在实际项目中,我们需要关注性能优化、用户体验和错误处理等方面,以确保功能的稳定性...
本文将介绍如何使用原生JavaScript实现类似jQuery中的animate()方法的动画效果。在前端开发中,jQuery提供了一套非常方便的API来实现动画效果,但随着Web标准的发展和性能优化需求的提高,原生JavaScript的方法逐渐...
本项目"js原生卡片式轮播图.zip"显然是一个用JavaScript原生代码实现的卡片式轮播图示例,无需依赖任何外部库,如jQuery或Bootstrap,这使得它在轻量化和自定义方面具有优势。 首先,我们来探讨一下卡片式轮播图的...
在 `szmarczak-http-timer-421d049` 这个压缩包中,可能包含了 `http-timer` 模块的源码,你可以查看其内部实现,了解它是如何与 Node.js 的 `http` 模块交互并实现计时功能的。这对于深入学习 Node.js 和网络编程...
### JavaScript 实现复合运动 #### 一、复合运动概述 复合运动是指在相同的动画执行时间段内,被选中的对象有多个属性(如宽度、高度、透明度等)同时发生改变的一种动画效果。这种方式相较于单一属性变化更为复杂...
在本篇文档中,作者分享了如何使用原生JavaScript实现一个动态的数码时钟特效。这个特效通过使用10张代表数字0-9的图片来显示时间,使得时钟具有视觉上的吸引力。以下是对实现这一特效的关键知识点的详细解释: 1. ...
【JavaScript源代码】原生JS运动实现轮播图 在网页设计中,轮播图是一种常见的展示多张图片或内容的交互方式。本教程将详细介绍如何使用原生JavaScript实现一个简单的图片轮播效果。基本原理是通过改变包含多张图片...
### JavaScript 实现加载进度条知识点解析 #### 一、引言 在Web开发中,加载进度条是一个非常实用的功能,能够提升用户体验,特别是在资源较大或网络条件不佳的情况下。本文将详细解析如何使用原生JavaScript(即不...
### JavaScript 实现移动小球与碰撞检测 #### 核心知识点概述 本示例通过原生 JavaScript 和 HTML 实现了一个动态的小球移动效果,并且具备基本的碰撞检测功能。主要涉及的技术点包括: 1. **CSS 样式设计**:为...
在本文中,我们将探讨如何使用原生JavaScript实现一个图片弹窗交互效果,主要涉及以下几个关键知识点: 1. **变量声明优化**: 在JavaScript中,使用`var`关键字声明变量是常见的做法。在代码示例中,为了提高效率...
在JavaScript编程中,实现长按鼠标左键弹出快捷菜单的效果是一种常见的交互设计,它可以提升用户的体验,使得操作更加便捷。这个代码示例是专为前端开发者设计的,旨在帮助他们在网页应用中集成这一功能,并确保兼容...
- 原型链:理解JavaScript的继承机制,原型对象的作用,以及如何使用原型链实现对象之间的关联。 4. **事件处理** - 事件监听:学习如何添加和移除事件监听器,处理用户输入和页面交互。 - 事件冒泡与捕获:理解...
1. 原生JavaScript实现图片按钮切换的基本概念和方法 原生JavaScript可以通过控制DOM元素来实现图片切换效果。上述代码段展示了如何通过编写JavaScript函数和对象原型来控制图片列表的滚动,实现图片按钮的切换功能...
React-Native之定时器Timer的实现代码 在 React-Native 中,定时器是一个非常重要的组件,提供了多种方法来实现定时器功能,包括 setTimeout、setInterval、setImmediate、clearTimeout、clearInterval、...
原生javascript实现无缝滚动是前端开发中常见的一个特效,它允许用户在浏览网页时,页面中的列表或者元素能够平滑地在指定方向上滚动。无缝滚动在很多地方都有应用,比如导航栏、公告栏、产品展示等。 首先,我们来...
总结,HTML实现Tab选项卡结合了HTML、CSS和JavaScript技术,通过合理的设计和交互逻辑,可以创建出既美观又实用的网页组件。自动和手动切换功能使用户可以根据需求自由控制信息的显示,提升了网页的易用性。在实际...
设计原则部分将指导开发者如何正确地使用RxJS库,包括如何构建和查询可观察序列(Observable sequences),如何处理错误,以及如何实现背压(Backpressure)等高级主题。 在“Getting Started with RxJS”部分,...
本项目名为"timer",它是一个基于原始JavaScript构建的计时器网络应用,没有依赖任何外部库,完全依靠HTML、CSS和JavaScript的原生能力来实现其功能。这为我们提供了一个很好的学习和实践JavaScript基础的机会。 **...