【问题标题】:setTimeout of a forEach loop with datetime countdown?带有日期时间倒计时的 forEach 循环的 setTimeout?
【发布时间】:2016-12-06 20:26:21
【问题描述】:

我正在尝试创建一个循环遍历 html 元素数组的脚本,并使用 setTimeout 为每个元素创建倒计时。我真的不知道为什么这不起作用,但这是我的代码,以及它给我的 console.log。 控制台日志 >

-1481055605166  testing.html:61:5
End  testing.html:64:5
days-> -17142-hours->-21-minutes->-21-second->-6  testing.html:75:5
NaN  testing.html:61:5
days-> NaN-hours->NaN-minutes->NaN-second->NaN  testing.html:75:5
NaN  testing.html:61:5
days-> NaN-hours->NaN-minutes->NaN-second->NaN*

这里是代码>

  var productos = document.querySelectorAll(".producto.med");

  function recorrido() {
    productos.forEach(function(item) {
      var hora = item.querySelector("#hasta");
      cdtd(hora);
    });
  }
  var timer = setTimeout(recorrido, 2000);

  function cdtd(dia) {
    var xmas = new Date(dia);
    var now = new Date();
    var timeDiff = xmas.getTime() - now.getTime();
    console.log(timeDiff);
    if (timeDiff <= 0) {
      clearTimeout(timer);
      console.log("End");
      // Run any code needed for countdown completion here
    }
    var seconds = Math.floor(timeDiff / 1000);
    var minutes = Math.floor(seconds / 60);
    var hours = Math.floor(minutes / 60);
    var days = Math.floor(hours / 24);
    hours %= 24;
    minutes %= 60;
    seconds %= 60;
    var total = 'days-> ' + days + '-hours->' + hours + '-minutes->' + minutes + '-second->' + seconds;
    console.log(total);
  }
<article class="producto med" id='{{$producto->id}}'>
  <h4>uno</h4>
  <div class="img-producto">
    <img src="{{$producto->ruta_imagen}}" alt="producto">
  </div>
  <div class="datos-producto">
    <ul class="tiempo">
      <li>desde: <span>{{$producto->fecha_inicio}}</span>
      </li>
      <li>hasta: <span id="hasta1">2016-12-12 15:45:00</span>
      </li>
    </ul>
    <p class="restante">tiempo restante:</p>
    <p class="tiempo">12hs 43m 03s</p>//JS PARA COUNTDOWNL
  </div>
  <a href="" class="ofertar">Ofertar ahora</a>
</article>
<article class="producto med" id='{{$producto->id}}'>
  <h4>dos</h4>
  <div class="img-producto">
    <img src="{{$producto->ruta_imagen}}" alt="producto">
  </div>
  <div class="datos-producto">
    <ul class="tiempo">
      <li>desde: <span>{{$producto->fecha_inicio}}</span>
      </li>
      <li>hasta: <span id="hasta">2017-12-12 15:45:00</span>
      </li>
    </ul>
    <p class="restante">tiempo restante:</p>
    <p class="tiempo">12hs 43m 03s</p>//JS PARA COUNTDOWNL
  </div>
  <a href="" class="ofertar">Ofertar ahora</a>
</article>
<article class="producto med" id='{{$producto->id}}'>
  <h4>tres</h4>
  <div class="img-producto">
    <img src="{{$producto->ruta_imagen}}" alt="producto">
  </div>
  <div class="datos-producto">
    <ul class="tiempo">
      <li>desde: <span>{{$producto->fecha_inicio}}</span>
      </li>
      <li>hasta: <span id="hasta">2016-12-12 15:45:00</span>
      </li>
    </ul>
    <p class="restante">tiempo restante:</p>
    <p class="tiempo">12hs 43m 03s</p>//JS PARA COUNTDOWNL
  </div>
  <a href="" class="ofertar">Ofertar ahora</a>
</article>

【问题讨论】:

标签: javascript arrays date settimeout


【解决方案1】:
  1. 第一个产品的 id 值为“hasta1”。这应该是“hasta

  2. HTML 元素应该有唯一的 ID。
    这可以通过

  3. 来实现

a) 使用“data-id”属性而不是“id”属性,改变所有

    <span id="hasta">

  进入

    <span data-id="hasta">

b) 通过改变让选择器找到这些元素

       var hora = item.querySelector("#hasta");

 到

       var hora = item.querySelector("[data-id=hasta]");
  1. Nan 值表示用于 Date 的数据值无效:这是因为 HTMLSpan 元素被传递给 cdtd,而不是字符串。解决此问题的一种方法是在 cdtd 的开头添加一条语句

      function cdtd(dia) {
    
       // get text before creating date
    
          dia = dia.textContent || dia.innerText;       
          var xmas = new Date(dia);
    
       // ... and continue  
    
  2. setTimeout 更改为setInterval,如

    var timer = setInterval(recorrido, 2000);
    

应该反复调用recorrido,直到计时器在cdtd 中停止(未测试)。为清楚起见,停止计时器可以使用clearInterval,尽管调用clearTimeoutclearInterval 执行相同的操作。


更新: 警告:如果类名也用于样式设置,请避免使用类选择器来查找元素。使用数据属性提供了另一种选择。

在此示例中,&lt;ul class="tiempo"&gt;&lt;p class="tiempo"&gt; 都匹配 .tiempo 的选择器。如果具有此类名称的元素将其内容设置为显示剩余时间,则列表元素将首先更新并销毁具有data-id="hasta" 属性的子元素。这会产生一个dianull

【讨论】:

  • 不错。 4.问题标题中的setTimeout应该在recorrido的末尾调用,而不是cdtd
  • @vp_arth 感谢您的反馈。看起来好像可以使用 setInterval 代替 setTimeout
  • 嘿它第一次工作,但后来它告诉我 dia 为空,我的意思是,该函数的第一次运行正常但随后 dia 为空
  • dia == null 表示item.querySelector("[data-id=hasta]"); 未找到任何元素。我无法重现该错误。在 2 秒后和 4 秒后调用 recorrido 不会引发异常。但是,我没有编译或扩展 HTML 模板代码。
【解决方案2】:

您似乎正在寻找页面中列出的内容:http://www.htmlgoodies.com/html5/javascript/calculating-the-difference-between-two-dates-in-javascript.html#fbid=S_-Ojf9buFk

只要你能计算出一个毫秒数 间隔,你可以通过除以总数得出一个数字 毫秒数乘以所需间隔中的毫秒数。 更重要的是,我们可以应用模数 (%) 运算符来去掉它 值来确定下一个更大的间隔。关键是要一直走 从最小间隔 - 毫秒 - 到最大 - 天:

Date.daysBetween = function( date1, date2 ) {
  //Get 1 day in milliseconds
  var one_day=1000*60*60*24;

  // Convert both dates to milliseconds
  var date1_ms = date1.getTime();
  var date2_ms = date2.getTime();

  // Calculate the difference in milliseconds
  var difference_ms = date2_ms - date1_ms;
  //take out milliseconds
  difference_ms = difference_ms/1000;
  var seconds = Math.floor(difference_ms % 60);
  difference_ms = difference_ms/60; 
  var minutes = Math.floor(difference_ms % 60);
  difference_ms = difference_ms/60; 
  var hours = Math.floor(difference_ms % 24);  
  var days = Math.floor(difference_ms/24);

  return days + ' days, ' + hours + ' hours, ' + minutes + ' minutes, and ' + seconds + ' seconds';
}

【讨论】:

    猜你喜欢
    • 2015-04-12
    • 2020-12-06
    • 2017-11-05
    • 1970-01-01
    • 1970-01-01
    • 2020-05-29
    • 2017-04-28
    • 1970-01-01
    • 2016-11-06
    相关资源
    最近更新 更多