问题

使用原生的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的定时器插件的更多相关文章

  1. JavaScript——BOM和DOM

    什么是BOM bom:浏览器对象模型 什么是DOM dom:文档对象模型 BOM操作: 调用windows浏览器窗口 windows对象可以通过点调用子对象 windows.navigator对象,可 ...

  2. Javascript事件绑定的几种方式

    Javascript的事件绑定主要有四种方法(一下在IE中运行正常,但不保证其他浏览器): [注:onXXX为某一事件,fun为某一function,domId为某一DOM对象id,event类型见后 ...

  3. javascript系列之DOM(三)---事件

    原文:javascript系列之DOM(三)---事件 事件是javascript跳动的心脏,是DOM所有成分结合的万金油.当我们在WEB 上进行某些交互时,事件也就发生了.点击某些内容,鼠标经过特定 ...

  4. 第一百二十一节,JavaScript事件绑定及深入

    JavaScript事件绑定及深入 学习要点: 1.传统事件绑定的问题 2.W3C事件处理函数 3.IE事件处理函数 4.事件对象的其他补充 事件绑定分为两种:一种是传统事件绑定(内联模型,脚本模型) ...

  5. Javascript事件模型(三):JavaScript事件绑定方法总结(及Jquery)

    JavaScript中绑定事件的方法主要有三种: 1 在DOM元素中直接绑定 2 JavaScript代码中直接绑定 3 绑定事件监听函数 JQuery中绑定事件的几种方法 主要有on().bind( ...

  6. JavaScript(1)---绑定事件、解除绑定事件

    JavaScript(1)---绑定事件.解除绑定事件 一.事件概述 1.事件的几个概念 · 事件 指的是文档或者浏览器窗口中发生的一些特定交互瞬间.我们可以通过侦听器(或者处理程序)来预定事件,以便 ...

  7. 【JavaScript基础】Js的定时器(你想看的原理也在哟)

    [JavaScript基础]Js的定时器(你想看的原理也在哟) 博客说明 文章所涉及的资料来自互联网整理和个人总结,意在于个人学习和经验汇总,如有什么地方侵权,请联系本人删除,谢谢! 说明 本章是经历 ...

  8. JavaScript进阶内容——DOM详解

    JavaScript进阶内容--DOM详解 当我们已经熟练掌握JavaScript的语法之后,我们就该进入更深层次的学习了 首先我们思考一下:JavaScript是用来做什么的? JavaScript ...

  9. 借助JavaScript中的Dom属性改变Html中Table边框的颜色

    借助JavaScript中的Dom属性改变Html中Table边框的颜色 -------------------- <html> <head> <title>我是页 ...

随机推荐

  1. topcoder SRM 623 DIV2 CatAndRat

    解决本题的一个关键点就是当Cat进入时,此时Rat在哪个位置? 注意移动方向可以随时改变,由于是圆环,故离入口最远点的距离是pi*R,即圆的一半, 当cat进入时(cat的速度大于rat的速度,否则不 ...

  2. gui学习

    GUI 图形用户界面(Graphical User Interface,简称 GUI,又称图形用户接口)是指采用图形方式显示的计算机操作用户界面 有名的实现 : ucgui   . 实现围绕几个问题: ...

  3. Nginx_HTTP 499 状态码 nginx下 499错误

    日志记录中HTTP状态码出现499错误有多种情况,我遇到的一种情况是nginx反代到一个永远打不开的后端,就这样了,日志状态记录是499.发送字节数是0. 老是有用户反映网站系统时好时坏,因为线上的产 ...

  4. Hadoop.2.x_WebUV示例

    一.网站基本指标(即针对于网站用户行为而产生的日志中进行统计分析) 1. PV:网页浏览量(Page View页面浏览次数,只要进入该网页就产生一条记录,不限IP,统计点每天(较多)/每周/每月/.. ...

  5. List集合对象根据字段排序

    //把需要比较的对象实现Comparable接口实现compareTo方法 public class Address implements Comparable<Address> { St ...

  6. Spark Kill Application

    yarn application -kill <applicationId>

  7. 调试WEB APP多设备浏览器

    方法:adobe shadow  \ opera远程调试\ weinre adobe shadow: 我们经常使用Firefox的firebug或者Chrome的开发人员工具进行Web调试页面,Jav ...

  8. SQL 参数化查询 应用于 Like

    在sql 进行参数化查询的时候,使用like 语句和参数的时候,错误的写法:  Participant like '%@Participant%' ,这样在数据库为解析为 '%'participant ...

  9. result结果集

    结果集(ResultSet)是数据中查询结果返回的一种对象,可以说结果集是一个存储查询结果的对象,但是结果集并不仅仅具有存储的功能,他同时还具有操纵数据的功能,可能完成对数据的更新等. 结果集读取数据 ...

  10. Sqlite 数据库出现database disk image is malformed报错的解决方法

    软件用的是Sqlite数据库,昨天还好好的,今天开机登录软件报错:database disk image is malformed 用Sqlite Expert Personal 重建索引,发现其中一 ...