zoukankan      html  css  js  c++  java
  • JavaScript实现绑定DOM的定时器插件

    问题

    使用原生的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

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

    image

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

    image

  • 相关阅读:
    抱歉
    The area
    sort
    Problem D
    Problem B
    错排
    第8集 仪表开关电源照明原理图
    第7集 驱动与电气原理图绘制
    第6集 初步使用EPLAN部件库部件功能
    第5集 软件中建立项目结构
  • 原文地址:https://www.cnblogs.com/lightsong/p/5467318.html
Copyright © 2011-2022 走看看