为每个元素数组设置间隔

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());

它会起作用。