首页 > 解决方案 > 尝试为各种任务创建 javascript 输出循环

问题描述

我正在尝试使用 javascript 来创建带有计数器的任务。该脚本将查找任务条目,然后根据数据库中的内容进行创建。例如 -

task 1 [timer 1]
task 2 [timer 2]
task 3 [timer 3]

目前我的输出是这样的

task 1 [timer 3]
task 2 [timer 3]
task 3 [timer 3]

我的代码如下-

{% if tasks %}

    {% for task in tasks %}

        <button class="button";>Complete!</button><p style="display: inline-block;font-weight: bold; color: red;">{{ task.task_name }}
            </p>
        <p></p>
        <p id='{{ task.id }}'; style="text-align: right;padding-right: 60px"></p>
        <p> <script>
                var countDownDate = new DateTime('{{ task.task_due }}').getTime();

                var x = setInterval(function() {

            var now = new Date().getTime();

            var distance = countDownDate - now;

            var days = Math.floor(distance / (1000 * 60 * 60 * 24));
            var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
            var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
            var seconds = Math.floor((distance % (1000 * 60)) / 1000);

            document.getElementById('{{ task.id }}').innerHTML = days + "d " + hours + "h "
            + minutes + "m " + seconds + "s ";

            if (distance < 0) {
            clearInterval(x);
            document.getElementById('{{ task.id }}').innerHTML = "EXPIRED";
            }
                }, 1000);
            </script>
        </p>
        <p></p>

感谢您的帮助,谢谢

标签: javascripthtml

解决方案


需要指出的几点:

  1. 在文档正文中设置所有这些vars 意味着它们都作用于全局window对象,这意味着每个循环都会覆盖相同的变量。这就是为什么您会看到timer3所有三个插槽的结果。
  2. (小问题)您的 HTML 中的一些地方有多余的分号。HTML 标记中不需要分号,除非它们位于接受它们的属性(例如属性)的引号style=""
  3. (小问题)与引号一致。一个好的通用样式原则是"double quotes"用于 HTML 属性,'single quotes'用于 Javascript 中的字符串。
  4. 您正在为循环的每次迭代创建重复的 javascript 代码for task in tasks。相反,您应该将该循环视为触发计时器启动并显示计时器结果的地方,但这不应该是所有计时器创建代码所在的位置。
  5. 要修复 (4),您需要从创建计时器的代码中创建一个可重用的函数。这是一个很好的测试用例,可以考虑需要将哪些函数参数传递给创建计时器的函数。在查看您的代码时,我看到您正在使用task.idtask.task_due在创建计时器的代码中。看起来我们只需要将这两个值传递给一个createTimer()函数。

尝试这样的事情:

<script>
  function createTimer(taskId, taskDue) {
    // just look this element up once for this timer
    var timerElement = document.getElementById(taskId);

    var countDownDate = new DateTime(taskDue).getTime();

    var timer = setInterval(function() {
      var now = new Date().getTime();
      var distance = countDownDate - now;

      if (distance < 0) {
        clearInterval(timer);
        timerElement.innerHTML = "EXPIRED";
      } else {
        var days = Math.floor(distance / (1000 * 60 * 60 * 24));
        var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
        var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
        var seconds = Math.floor((distance % (1000 * 60)) / 1000);

        var timerDisplay = `${days}d ${hours}h ${minutes}m ${seconds}s`;
        timerElement.innerHTML = timerDisplay;
      }
    }, 1000);
  }
</script>


{% if tasks %}
  {% for task in tasks %}
    <button class="button">Complete!</button>

    <p style="display:inline-block; font-weight:bold; color:red;">
      {{ task.task_name }}
    </p>

    <p id="{{ task.id }}" style="text-align:right; padding-right:60px"></p>

    <!-- call the function to start this timer -->
    <script>createTimer('{{ task.id }}', '{{ task.task_due }}')</script>
  {% endfor %}
{% endif %}

推荐阅读