为每个元素数组设置间隔
setInterval for each of an array of elements
我有一组 DOM 个元素,每个元素都需要自己的计时器。最终,我将每隔 X 毫秒检查一次,以查看该元素的特定子元素是否存在,但目前计时器内部发生的事情并不重要。
问题是我希望计时器最终 停止。我可以用 setInterval 设置计时器,它们工作正常,但我不知道如何让 clearInterval 结束它们。
我可能可以用一个监视每个相关元素的大计时器来做到这一点,但现在我很好奇并想弄清楚这一点。我想我可能在声明或启动计时器的方式上做错了什么,或者 clearInterval 错误地针对 setInterval 函数。
这是我当前的代码:
$(document).ready(function () {
let interval = 1000;
let base_count = 1;
let current_counts = [];
let timers = [];
// Count up from base to max and update the text to match.
function counter(p, maxCount, i) {
p.text(p.text().slice(0,5) + ': ' + current_counts[i]);
if (current_counts[i] > maxCount) {
clearInterval(timers[i]);
}
current_counts[i]++;
}
// Counters for each thing start at 1
current_counts = Array($('.thing').length).fill(base_count);
// Each thing gets its own timer.
timers = $('.thing').map(function (i, e) {
function start() {
return setInterval(
counter,
interval,
$(e),
10, // Max value for counter
i // Which paragraph are we on?
);
}
return start;
});
// Start the timers.
timers.each((i, e) => e());
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p class="test1 thing">Test1</p>
<p class="test2 thing">Test2</p>
<p class="test3 thing">Test3</p>
正如@pilchard 所说,MutationObserver 应该适合您的用例。虽然这不能回答您的问题,但这里是答案:
在浏览器上 setInterval
returns 创建的间隔 ID,因此您可以在 clearInterval
上使用它,如下所示:
// create the interval
let intervalId = setInterval(callback, time);
// clear the interval using the id
clearInverval(intervalId);
e()
returns 所有计时器,然后简单地稍后清除它们
var tmrs = timers.map((i, e) => e());
// stop all timers
tmrs.forEach(x=> clearInverval(x)))
Mutation observer 虽然没有得到普遍支持,但得到了广泛的支持,这也是我在这里使用的。但是您的代码也可以工作并且会得到更广泛的支持。您声明了数组 current_counts,但您从未为其分配任何值,因此 current_counts[i] 将始终未定义,并且您的检查将始终失败。
if (current_counts[i] > maxCount) {
clearInterval(timers[i]);
}
您没有在任何地方存储间隔。
如果您更改以下内容:
timers.each((i, e) => e());
至:
timers = timers.map((i, e) => e());
它会起作用。
我有一组 DOM 个元素,每个元素都需要自己的计时器。最终,我将每隔 X 毫秒检查一次,以查看该元素的特定子元素是否存在,但目前计时器内部发生的事情并不重要。
问题是我希望计时器最终 停止。我可以用 setInterval 设置计时器,它们工作正常,但我不知道如何让 clearInterval 结束它们。
我可能可以用一个监视每个相关元素的大计时器来做到这一点,但现在我很好奇并想弄清楚这一点。我想我可能在声明或启动计时器的方式上做错了什么,或者 clearInterval 错误地针对 setInterval 函数。
这是我当前的代码:
$(document).ready(function () {
let interval = 1000;
let base_count = 1;
let current_counts = [];
let timers = [];
// Count up from base to max and update the text to match.
function counter(p, maxCount, i) {
p.text(p.text().slice(0,5) + ': ' + current_counts[i]);
if (current_counts[i] > maxCount) {
clearInterval(timers[i]);
}
current_counts[i]++;
}
// Counters for each thing start at 1
current_counts = Array($('.thing').length).fill(base_count);
// Each thing gets its own timer.
timers = $('.thing').map(function (i, e) {
function start() {
return setInterval(
counter,
interval,
$(e),
10, // Max value for counter
i // Which paragraph are we on?
);
}
return start;
});
// Start the timers.
timers.each((i, e) => e());
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p class="test1 thing">Test1</p>
<p class="test2 thing">Test2</p>
<p class="test3 thing">Test3</p>
正如@pilchard 所说,MutationObserver 应该适合您的用例。虽然这不能回答您的问题,但这里是答案:
在浏览器上 setInterval
returns 创建的间隔 ID,因此您可以在 clearInterval
上使用它,如下所示:
// create the interval
let intervalId = setInterval(callback, time);
// clear the interval using the id
clearInverval(intervalId);
e()
returns 所有计时器,然后简单地稍后清除它们
var tmrs = timers.map((i, e) => e());
// stop all timers
tmrs.forEach(x=> clearInverval(x)))
Mutation observer 虽然没有得到普遍支持,但得到了广泛的支持,这也是我在这里使用的。但是您的代码也可以工作并且会得到更广泛的支持。您声明了数组 current_counts,但您从未为其分配任何值,因此 current_counts[i] 将始终未定义,并且您的检查将始终失败。
if (current_counts[i] > maxCount) {
clearInterval(timers[i]);
}
您没有在任何地方存储间隔。
如果您更改以下内容:
timers.each((i, e) => e());
至:
timers = timers.map((i, e) => e());
它会起作用。