`
rainsilence
  • 浏览: 160561 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

JavaScript Timer实现 (原)

阅读更多
前言:最近开始接触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,明天换了。你又要从头开始了。
4
0
分享到:
评论
1 楼 sunxubo 2012-01-05  
看了你写的这些文章,很崇拜你。我有一年多的开发经验,想在编程方面有所提升,可不可以给我推荐几本好书看下,不论是前台js,还是java方面的都可以,谢谢啦!

相关推荐

    【JavaScript源代码】原生JS实现图片轮播 JS实现小广告插件.docx

    ### 原生JavaScript实现图片轮播功能 #### 背景介绍 本文档主要介绍了如何使用原生JavaScript实现一个图片轮播的功能。这个轮播功能不仅能够满足基本的自动循环播放图片的需求,还能实现通过点击左右箭头来手动切换...

    ajax_timer.

    综上所述,`ajax_timer`是利用AJAX和JavaScript定时器功能实现的,用于周期性地向服务器发送请求,获取更新数据并展示在网页上。在实际项目中,我们需要关注性能优化、用户体验和错误处理等方面,以确保功能的稳定性...

    原生js实现jquery函数animate()动画效果的简单实例

    本文将介绍如何使用原生JavaScript实现类似jQuery中的animate()方法的动画效果。在前端开发中,jQuery提供了一套非常方便的API来实现动画效果,但随着Web标准的发展和性能优化需求的提高,原生JavaScript的方法逐渐...

    js原生卡片式轮播图.zip

    本项目"js原生卡片式轮播图.zip"显然是一个用JavaScript原生代码实现的卡片式轮播图示例,无需依赖任何外部库,如jQuery或Bootstrap,这使得它在轻量化和自定义方面具有优势。 首先,我们来探讨一下卡片式轮播图的...

    Node.js-http-timer对HTTP请求进行计时

    在 `szmarczak-http-timer-421d049` 这个压缩包中,可能包含了 `http-timer` 模块的源码,你可以查看其内部实现,了解它是如何与 Node.js 的 `http` 模块交互并实现计时功能的。这对于深入学习 Node.js 和网络编程...

    【JavaScript源代码】原生JS实现各种运动之复合运动.docx

    ### JavaScript 实现复合运动 #### 一、复合运动概述 复合运动是指在相同的动画执行时间段内,被选中的对象有多个属性(如宽度、高度、透明度等)同时发生改变的一种动画效果。这种方式相较于单一属性变化更为复杂...

    【JavaScript源代码】原生JS实现数码表特效.docx

    在本篇文档中,作者分享了如何使用原生JavaScript实现一个动态的数码时钟特效。这个特效通过使用10张代表数字0-9的图片来显示时间,使得时钟具有视觉上的吸引力。以下是对实现这一特效的关键知识点的详细解释: 1. ...

    【JavaScript源代码】原生JS运动实现轮播图.docx

    【JavaScript源代码】原生JS运动实现轮播图 在网页设计中,轮播图是一种常见的展示多张图片或内容的交互方式。本教程将详细介绍如何使用原生JavaScript实现一个简单的图片轮播效果。基本原理是通过改变包含多张图片...

    【JavaScript源代码】原生JS实现加载进度条.docx

    ### JavaScript 实现加载进度条知识点解析 #### 一、引言 在Web开发中,加载进度条是一个非常实用的功能,能够提升用户体验,特别是在资源较大或网络条件不佳的情况下。本文将详细解析如何使用原生JavaScript(即不...

    【JavaScript源代码】原生js实现移动小球(碰撞检测).docx

    ### JavaScript 实现移动小球与碰撞检测 #### 核心知识点概述 本示例通过原生 JavaScript 和 HTML 实现了一个动态的小球移动效果,并且具备基本的碰撞检测功能。主要涉及的技术点包括: 1. **CSS 样式设计**:为...

    原生javascript实现图片弹窗交互效果

    在本文中,我们将探讨如何使用原生JavaScript实现一个图片弹窗交互效果,主要涉及以下几个关键知识点: 1. **变量声明优化**: 在JavaScript中,使用`var`关键字声明变量是常见的做法。在代码示例中,为了提高效率...

    JavaScript长按鼠标左键弹出快捷菜单效果代码

    在JavaScript编程中,实现长按鼠标左键弹出快捷菜单的效果是一种常见的交互设计,它可以提升用户的体验,使得操作更加便捷。这个代码示例是专为前端开发者设计的,旨在帮助他们在网页应用中集成这一功能,并确保兼容...

    JavaScript网页设计300例

    - 原型链:理解JavaScript的继承机制,原型对象的作用,以及如何使用原型链实现对象之间的关联。 4. **事件处理** - 事件监听:学习如何添加和移除事件监听器,处理用户输入和页面交互。 - 事件冒泡与捕获:理解...

    原生javascript实现图片按钮切换

    1. 原生JavaScript实现图片按钮切换的基本概念和方法 原生JavaScript可以通过控制DOM元素来实现图片切换效果。上述代码段展示了如何通过编写JavaScript函数和对象原型来控制图片列表的滚动,实现图片按钮的切换功能...

    React-Native之定时器Timer的实现代码

    React-Native之定时器Timer的实现代码 在 React-Native 中,定时器是一个非常重要的组件,提供了多种方法来实现定时器功能,包括 setTimeout、setInterval、setImmediate、clearTimeout、clearInterval、...

    原生javascript实现无间缝滚动示例

    原生javascript实现无缝滚动是前端开发中常见的一个特效,它允许用户在浏览网页时,页面中的列表或者元素能够平滑地在指定方向上滚动。无缝滚动在很多地方都有应用,比如导航栏、公告栏、产品展示等。 首先,我们来...

    HTML实现Tab选项卡(自动+手动)

    总结,HTML实现Tab选项卡结合了HTML、CSS和JavaScript技术,通过合理的设计和交互逻辑,可以创建出既美观又实用的网页组件。自动和手动切换功能使用户可以根据需求自由控制信息的显示,提升了网页的易用性。在实际...

    Reactive Extensions for javascript

    设计原则部分将指导开发者如何正确地使用RxJS库,包括如何构建和查询可观察序列(Observable sequences),如何处理错误,以及如何实现背压(Backpressure)等高级主题。 在“Getting Started with RxJS”部分,...

    timer:一个计时器网络应用,该应用可实现使用原始JavaScript创建的基本功能。 没有库,只有纯HTML和CSS

    本项目名为"timer",它是一个基于原始JavaScript构建的计时器网络应用,没有依赖任何外部库,完全依靠HTML、CSS和JavaScript的原生能力来实现其功能。这为我们提供了一个很好的学习和实践JavaScript基础的机会。 **...

Global site tag (gtag.js) - Google Analytics