试图运行你的小提琴,Chrome 抱怨 jquery.offput.ca,它称之为“已知分发恶意软件”的网站。如果我去看那个 jQuery 插件的演示,我会得到同样的警告。因此,我无法使用该实际代码。 在您更新时,我可以使用您的实际代码,因此请参阅此答案的最后,以使用您的原始代码获得答案。不过,我将保留非计时器插件的答案。
该元素可能会或可能不会保留在内存中,这完全取决于计时器插件的工作方式。不过,重要的是,无论元素是否在内存中,都不会停止计时器。你需要代码来做到这一点。
我从未使用过该计时器插件,但大概它有一些方法可以告诉计时器停止,可能是通过您对已附加计时器的元素的 jQuery 包装器进行的调用。因此,在您的Remove
函数中,您需要一种方法来识别带有计时器的元素,以便您可以停止它们。
这是一个不使用计时器插件的示例,以演示这些概念。以下是我的做法:
当我创建setInterval
计时器时,我记得一个名为data-timer-handle
. 您可能需要也可能不需要,但您需要在元素上放置某种标记,以便告诉计时器插件停止。
在Remove
中,在清除之前#main
,我找到它具有属性的任何子项data-timer-handle
并清除间隔计时器。
现场复制| 来源:
HTML:
<div id="main">
<div id="timerpanel">I'm the timer panel</div>
</div>
<input type="button" id="removeButton" value="Remove It">
<div id="debug"></div>
JavaScript:
function TimerTest(panelId)
{
this.PanelID = panelId;
}
TimerTest.prototype.Start = function()
{
var self = this;
// Start the timer
var handle = setInterval(function() {
self.Print();
}, 1000);
// Remember the handle on a data-timer-handle property
// on the element.
$(document.getElementById(this.PanelID)).attr("data-timer-handle", handle);
}
TimerTest.prototype.Print = function()
{
$("#debug").append("<div>triggered...</div>");
}
function Remove()
{
var main = $("#main");
// Find any elements with timers on them, stop them
main.find("[data-timer-handle]").each(function() {
clearInterval($(this).attr("data-timer-handle"));
});
main.html("I'm done!");
}
$(document).ready(function(){
var timer = new TimerTest("timerpanel");
timer.Start();
$("#removeButton").click(function() {
Remove();
});
});
如果我正在编写一个将计时器附加到元素的计时器插件,我肯定会在元素中添加一些东西(data-*
属性、类等),以便您再次找到它们。但是,我还提供了一个选项,用于在元素从 DOM 中删除时自动取消计时器(这样您就不需要查找和停止它们),方法是让每个计时器滴答声检查元素是否仍然存在随附的。(默认情况下我可能不会启用它,但它会是一个选项。)
在下面回复您的评论:
不过,我对您的代码有疑问:它确实停止了计时器,但是我怎么知道它实际上破坏了TimerTest
-object?计时器只是我说的一种方式。AFAIK 计时器本身没有对TimerTest
-object 的引用,那么为什么该对象仍然存在?您可以通过修改 Print() 来打印“this.PanelID”`
啊,但是计时器确实保留了对TimerTest
实例的引用:您传递给计时器的函数是一个闭包。它引用了创建它的范围内的所有内容,包括self
引用该对象的变量TimerTest
(当然,否则self.Print()
将不起作用)。因此,只要该函数存在,它就会将TimerTest
实例保存在内存中。
那么是什么将这个函数保存在内存中呢?计时器对它的引用。只要计时器还活着,它就有一个对该函数的引用,并将该函数保存在内存中。在我上面的示例中,clearInterval
删除了对函数的引用,使其符合垃圾回收的条件;这意味着该函数不再将它关闭的东西保存在内存中。如果该函数是唯一对实例具有突出引用的事物TimerTest
,则意味着该TimerTest
实例有资格进行垃圾回收。
在我的代码中,没有任何东西将元素保留在内存中(您正在使用的计时器插件可能不是这样),但是TimerTest
只要浏览器的setInterval
东西正在使用该函数,该函数就会使该实例保持活动状态。
更多探索:
现在你的小提琴没有链接到那个(也许)狡猾的网站:
我惊讶地发现,计时器插件似乎并没有在元素中添加任何东西,以便再次轻松找到。没关系,这对我们来说是微不足道的。
更改Start
以标记元素 - 这里我使用了一个类:
TimerTest.prototype.Start = function()
{
var self = this;
$("#" + this.PanelID)
.addClass("hastimer")
.everyTime("1s", "Test", function(){
self.Print();
});
};
(我还使用 jQuery 来查找元素,而不是document.getElementById
。并且您希望在函数表达式的末尾使用分号。)
并更改Remove
为在该类的所有元素上停止计时器:
function Remove()
{
var main = $("#main");
main.find(".hastimer").stopTime();
main.html("I'm done!");
}
empty
(在调用之前无需调用html
;html
调用empty
。)
更新的小提琴