首页 > 解决方案 > .each() 中的 setInterval 仅适用于最后一个间隔?

问题描述

目标:

我使用 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)
});

标签: javascriptjquerysetintervaleachcountdown

解决方案


问题是当你的区间内的函数运行时循环已经完成,所以$event只会引用.eventjQuery 对象中的最后一个元素。

假设您可以使用 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));
});

推荐阅读