在动态加载上清除javascript

时间:2011-07-01 08:59:20

标签: javascript jquery html settimeout clear

我有一个特殊图像滚动条的javascript插件。滚动条包含一堆超时方法和许多带有这些超时设置值的变量。

一切都很完美,但对于我正在处理的网站,要求页面是动态加载的。这个问题是当我改变网站上的语言时,这是由jquery加载函数创建的,意味着内容被动态加载到网站上 - 以及图像滑块。

现在这是一个大问题!当我第二次动态加载图像滑块时,我以前的所有值都与定时器和其他所有值一样。 有没有办法清除javascript插件中的所有内容,就像重新加载页面一样?

到目前为止,我已经尝试过很多东西,所以我会非常感谢你们的帮助!

非常感谢!

1 个答案:

答案 0 :(得分:0)

您可能需要这样的东西来重新加载脚本:

<script class="persistent" type="text/javascript">      
  function reloadScripts()
  { [].forEach.call(document.querySelectorAll('script:not(.persistent)'), function(oldScript)
    { 
      var newScript = document.createElement('script');

      newScript.text = oldScript.text;
      for(var i=0; i<oldScript.attributes.length; i++)
        newScript.setAttribute(oldScript.attributes[i].name, oldScript.attributes[i].value);

      oldScript.parentElement.replaceChild(newScript, oldScript);
    });
  }

  // test
  setInterval(reloadScripts, 5000);
</script>

据我所知,除了完全删除旧脚本并创建另一个具有相同属性和内容的脚本之外,没有其他方法可以重置脚本。甚至克隆节点都不会重置脚本,至少在Firefox中。

你说你想重置计时器。您的意思是clearTimeout()clearInterval()吗?方法Window.prototype.setTimeout()Window.prototype.setInterval()都会返回一个ID,以传递给clearTimeout()的后续调用。不幸的是,没有内置功能可以清除任何活动计时器。

我写了一些代码来注册所有的计时器ID。用于实现setTimeout的包装器回调的简单TODO任务尚未打开。该功能没有故障,但过多调用setTimeout可能会搞乱阵列。

请注意,扩展宿主对象的原型会导致未定义的行为,因为暴露主机原型和内部行为不是W3C规范的一部分。浏览器可以改变这种未来。另一种方法是将代码直接放入window对象中,然而,并不是绝对确定其他脚本会调用这些修改过的方法。这两个决定都不是最佳选择。

  (function()
  { // missing in older browsers, e.g. IE<9
    if(!Array.prototype.indexOf)
      Object.defineProperty(Array.prototype, 'indexOf', {value: function(needle, fromIndex)
      { // TODO: assert fromIndex undefined or integer >-1
        for(var i=fromIndex || 0; i < this.length && id !== window.setTimeout.allIds[i];) i++;
        return i < this.length ? i : -1;
      }});

    if(!Array.prototype.remove)
      Object.defineProperty(Array.prototype, 'remove', { value: function(needle) 
      { var i = this.indexOf(needle);
        return -1 === i ? void(0) : this.splice(i, 1)[0]; 
      }});


    // Warning: Extensions to prototypes of host objects like Window can cause errors
    //          since the expose and behavior of host prototypes are not obligatory in
    //          W3C specs.
    //          You can extend a specific window/frame itself, however, other scripts
    //          could get around when they call window.prototype's methods directly.
    try
    {
      var
        oldST = setTimeout,
        oldSI = setInterval,
        oldCT = clearTimeout,
        oldCI = clearInterval
      ;
      Object.defineProperties(Window.prototype, 
      {
        // TODO: write a wrapper that removes the ID from the list when callback is executed
        'setTimeout':
        { value: function(callback, delay)
          {
            return window.setTimeout.allIds[window.setTimeout.allIds.length]
              = window.setTimeout.oldFunction.call(this, callback, delay);
          }
        },

        'setInterval':
        { value: function(callback, interval)
          {
            return window.setInterval.allIds[this.setInterval.allIds.length]
              = window.setInterval.oldFunction.call(this, callback, interval);
          }
        },

        'clearTimeout':
        { value: function(id)
          { debugger;
            window.clearTimeout.oldFunction.call(this, id);
            window.setTimeout.allIds.remove(id);
          }
        },

        'clearInterval':
        { value: function(id)
          {
            window.clearInterval.oldFunction.call(this, id);
            window.setInterval.allIds.remove(id);
          }
        },

        'clearTimeoutAll' : { value: function() { while(this.setTimeout .allIds.length) this.clearTimeout (this.setTimeout .allIds[0]); } },
        'clearIntervalAll': { value: function() { while(this.setInterval.allIds.length) this.clearInterval(this.setInterval.allIds[0]); } },
        'clearAllTimers'  : { value: function() { this.clearIntervalAll(); this.clearTimeoutAll(); } }
      });

      window.setTimeout   .allIds      = [];
      window.setInterval  .allIds      = [];
      window.setTimeout   .oldFunction = oldST;
      window.setInterval  .oldFunction = oldSI;
      window.clearTimeout .oldFunction = oldCT;
      window.clearInterval.oldFunction = oldCI;
    } 
    catch(e){ console.log('Something went wrong while extending host object Window.prototype.\n', e); }
  })();

这为每个本机方法提供了一个包装器方法。它将调用本机函数并在方法的Function对象中跟踪数组中返回的ID。请记住实施TODO。