我有一个特殊图像滚动条的javascript插件。滚动条包含一堆超时方法和许多带有这些超时设置值的变量。
一切都很完美,但对于我正在处理的网站,要求页面是动态加载的。这个问题是当我改变网站上的语言时,这是由jquery加载函数创建的,意味着内容被动态加载到网站上 - 以及图像滑块。
现在这是一个大问题!当我第二次动态加载图像滑块时,我以前的所有值都与定时器和其他所有值一样。 有没有办法清除javascript插件中的所有内容,就像重新加载页面一样?
到目前为止,我已经尝试过很多东西,所以我会非常感谢你们的帮助!
非常感谢!
答案 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。