.each()中的setInterval仅适用于最后一个间隔?

时间:2020-07-27 09:34:08

标签: javascript jquery setinterval each countdown

目标:

我使用jQuery的each函数遍历几个.event元素。我正在使用来自每个.event类中隐藏的span元素的信息来计算计时器倒计时。我正在使用setInterval()每秒重新计算剩余时间。

问题:

我的所有计算均能完美完成-但仅适用于最后间隔。每个间隔似乎都覆盖了之前的计算。含义:只有最后一个.event甚至得到输出。以前的所有.event甚至都没有得到任何输出。使用间隔前后的日志,我可以将错误范围缩小到setInterval函数。如何防止每个间隔覆盖之前的间隔?还是我的错误是我什至没有想到的地方?

代码:

$('.event').each(function() {
    $event = $(this);

    // SET FUTURE DATE
    $futureDate = $event.find($('.event-time'));
    $countdownDate = new Date($futureDate.text()).getTime();

    setInterval(function() {
    
        // SET TODAYS DATE
        $now = new Date().getTime();
    
        // DIFFERENCE NOW AND FUTURE DATE
        $diff = $countdownDate - $now;
    
        // TIME CALCULATIONS FOR d, h, m, s
        $days = Math.floor($diff / (1000 * 60 * 60 * 24));
        $hours = Math.floor(($diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
        $minutes = Math.floor(($diff % (1000 * 60 * 60)) / (1000 * 60));
        $seconds = Math.floor(($diff % (1000 * 60)) / 1000);
    
        // OUTPUT
        $event.find('.clock .val-d').html($days);
        $event.find('.clock .val-h').html($hours);
        $event.find('.clock .val-m').html($minutes);
        $event.find('.clock .val-s').html($seconds);
    
    }, 1000)
});

1 个答案:

答案 0 :(得分:4)

问题是因为当间隔内的函数运行循环时,所以$event只会引用jQuery对象中的最后一个.event元素。

假设您可以使用ES6,最简单的解决方法是使用let关键字定义$event

$('.event').each(function() {
  let $event = $(this);

  // the rest of your code...
});

如果您不能使用ES6,则需要使用闭包来保留$(this)的范围:

$('.event').each(function() {
  (function($event) {
    $futureDate = $event.find($('.event-time'));
    $countdownDate = new Date($futureDate.text()).getTime();

    setInterval(function() {
      $now = new Date().getTime();
      $diff = $countdownDate - $now;

      // TIME CALCULATIONS FOR d, h, m, s
      $days = Math.floor($diff / (1000 * 60 * 60 * 24));
      $hours = Math.floor(($diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
      $minutes = Math.floor(($diff % (1000 * 60 * 60)) / (1000 * 60));
      $seconds = Math.floor(($diff % (1000 * 60)) / 1000);

      $event.find('.clock .val-d').html($days);
      $event.find('.clock .val-h').html($hours);
      $event.find('.clock .val-m').html($minutes);
      $event.find('.clock .val-s').html($seconds);
    }, 1000)
  })($(this));
});