码迷,mamicode.com
首页 > 编程语言 > 详细

JavaScript实现绑定DOM的定时器插件

时间:2016-05-06 23:33:46      阅读:618      评论:0      收藏:0      [点我收藏+]

标签:

问题

使用原生的setTimeout和setInterval仅仅能够实现, 定时执行事件处理函数,

在网页开发中, 往往会出现一种情况,定时器用于定时更新某个页面区域的数据,

往往在页面加载之后, 就启动这个定时器, 往后则间隔执行此定时器。

 

页面上定时刷新的区域可能会动态消失, 特别是在ajax被广泛使用的今天,

如果定时刷新的区域被删除了, 则定时器材也需要自动清除掉。

 

此二个接口,如果实现这种效果需要, 自己维护定时器句柄, 并且在处理定时器事件函数的时候,

首先判断 指定的刷新区域是否还是存在的?  如果还存在, 则继续执行数据刷新的逻辑,

如果不存在, 则删除定时器,不执行数据刷新的动作。

 

方案

此类定时器需要与 目标DOM进行绑定, 在事件处理函数中, 判断如果DOM被删除, 则清理定时器。

 

Code

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>My First WebComponent</title>
</head>
<body>
    <input type="text" id="test" name="test" value="test"></input>
    <input type="button" id="removetest" name="removetest" value="removetest"></input>
    <script type="text/javascript">
    /************************ timer定时器插件 start **********************/
    (function () {
        /* 此函数让 定时器处理handler,
            可以获取到 调用 setTimeout_context_binding 的对象 */
        var setTimeout_context_binding = function (vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */) {
          var oThis = this, aArgs = Array.prototype.slice.call(arguments, 2);
          return window.setTimeout(vCallback instanceof Function ? function () {
                vCallback.apply(oThis, aArgs);
          } : vCallback, nDelay);
        };

        /* 此函数让 定时器处理handler,
            可以获取到 调用 setTimeout_context_binding 的对象 */
        var setInterval_context_binding = function(vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */ ) {
            var oThis = this, aArgs = Array.prototype.slice.call(arguments, 2);
            return window.setInterval(vCallback instanceof Function ? function() {
                vCallback.apply(oThis, aArgs);
            } : vCallback, nDelay);
        };

        /* 定义定时器的构造函数 */
        var timer = function(fnAlarm, options)
        {
            /* external settable */
            this.fnAlarm_inner = function(){
                $("#timer_msg").printMsg(this.timerHandle.toString()
                    + "-please add custom fnAlarm")
            };

            this.timeout = undefined;
            this.interval = undefined;
            this.contextDom = undefined;

            /* inner maintain variable */
            this.timerHandle;

            /* set external variable */
            if ( fnAlarm )
            {
                this.fnAlarm_inner = fnAlarm;
            }

            if ( options )
            {
                if ( options.timeout )
                {
                    this.timeout = options.timeout;
                }

                if ( options.interval )
                {
                    this.interval = options.interval;
                }

                if ( options.contextDom )
                {
                    this.contextDom = options.contextDom;
                }
            }
        }

        /* 定义定时器的原型方法 */
        timer.prototype.start = function(){
            var context_binding_timer = undefined;
            var time_value = undefined;

            if ( this.timeout ) {
                context_binding_timer = setTimeout_context_binding;
                time_value = this.timeout;
            } else {
                context_binding_timer = setInterval_context_binding;
                time_value = this.interval;
            }

            this.timerHandle = context_binding_timer.call(this, function(){
                /* 上下文DOM绑定的目的在这里:
                    如果此定时器绑定的DOM已经从文档中删除,则不调用定时处理handler */
                if ( this.contextDom && !document.body.contains(this.contextDom) )
                {
                    this.stop();
                    return;
                }

                this.fnAlarm_inner.call(this);
                delete this.timerHandle;
            }, time_value);
        };

        timer.prototype.stop = function(){
            if ( this.timeout ) {
                clearTimeout(this.timerHandle)
            } else {
                clearInterval(this.timerHandle)
            }
            delete this.timerHandle;
        };

        timer.prototype.getTimerID = function(){
            return this.timerHandle;
        };

        /* 开放接口 */
        window.ContextBindingTimer = timer;
    })();
    /************************ timer定时器插件 end **********************/

    //bind remove button event
    document.getElementById("removetest").onclick=function(){
        var test = document.getElementById("test");
        test.parentNode.removeChild(test);
    }

    var targetDom = document.getElementById("test");

    /* construct a interval timer with setTimeout timer */
    var timer = new ContextBindingTimer(function(){
        console.log("access once!")
    }, {timeout:1000, contextDom:targetDom})
       
    timer.start()
    </script>
</body>
</html>

 

Implementation effect

页面上输入框删除之前, 定时器打印数目一直增加。

技术分享

点击按钮删除输入框之后, 定时器打印数据则没有变化了, 证明定时器已经被删除。

技术分享

JavaScript实现绑定DOM的定时器插件

标签:

原文地址:http://www.cnblogs.com/lightsong/p/5467318.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!