【问题标题】:Update html label from for loop not working从 for 循环更新 html 标签不起作用
【发布时间】:2022-08-14 13:17:51
【问题描述】:

我有一个 ajax 调用来获取学生的出勤率。它被填充到名为 \'#tableAttendance\' 的表中。执行时,我将显示一个模式(如弹出进度窗口)以显示进度加载进度(加载 100 个中的 1 个)。在 for 循环中,我需要更新一个名为 \"#LoadingRecord\" 的标签,其中包含每轮加载的记录数。在我的代码中,标签只会在执行 for 循环后更新,即使标签更新代码在循环内(可能是线程阻塞)。我怎样才能接近这个功能?

有没有办法至少将 for 循环暂停 1 毫秒以更新标签(\'loading 2 of 100\')并继续下一轮循环?

应该能够在标签中显示循环的当前位置喜欢进度条
在第一轮\'加载 1 of 100\',
在第二轮\'加载 2 of 100\',
在第三轮\'加载 3 of 100\'

但是在控制台上实时显示循环
\'正在加载 100 个中的 1 个\'
\'正在加载 2 个,共 100 个\'
\'正在加载 3 个,共 100 个\'
.....................
\'加载 100 个中的 100 个\'

我的模态:

<div class=\"modal\" tabindex=\"-1\" role=\"dialog\" aria-hidden=\"true\">
        <div class=\"modal-dialog\" style=\"width:auto;\">
            <div class=\"modal-content\">
                <div class=\"modal-body\" style=\"margin-top: -25px;\">
                    <label id=\"LoadingRecord\"></label>
                </div>
            </div>
        </div>
    </div>

我的代码:

$.ajax({
            url: $(\"#GetAttendance\").val(),
            type: \"POST\",
            dataType: \"JSON\",
            data: { StudentID: $(\"#StudentID\").val()},
            success: function (result) {
                for (var i = 0; i < result.length; i++) {
                    console.log(\"loading \" + (i+1) + \" of \" + result.length));
                    window.requestAnimationFrame(()=> $(\"#LoadingRecord\").text(\"loading \" + (i+1) + \" of \" + result.length)); //this label  should be updated each round, but it does not
                    var row = $(\'#tableAttendance tbody>tr:last\').clone(true);
                    row.find(\'label[name=\"Date\"]\').val(result[i].Date);
                    row.find(\'label[name=\"Presence\"]\').val(result[i].AbsentOrPresent);
                    row.insertAfter(\'#tableAttendance tbody>tr:last\');
                }
            }
        });
  • 欢迎来到堆栈溢出。最有可能的是,您有多个标签并且调用 $(\"#Label\") 可能会产生多个结果。请提供一个最小的、可重现的示例:stackoverflow.com/help/minimal-reproducible-example
  • @Twisty 更新了问题。
  • 更新不显示任何新的细节。请提供更完整的示例。
  • @Twisty 我也添加了模态
  • 由于只有一个标签,您希望如何附加结果?

标签: javascript jquery for-loop jquery-ui


【解决方案1】:

考虑以下。

$.ajax({
  url: $("#GetAttendance").val(),
  type: "POST",
  dataType: "JSON",
  data: {
    StudentID: $("#StudentID").val()
  },
  success: function(result) {
    $.each(result, function(i, o) {
        $("#LoadingRecord").append((i + 1) + " of " + result.length + "<br />");
        var row = $('#tableAttendance tbody>tr:last').clone(true);
        $('label[name="Date"]', row).val(o.Date);
        $('label[name="Presence"]', row).val(o.AbsentOrPresent);
        $('#tableAttendance tbody').append(row);
      }
    });
});

您可以看到这将在标签中添加一个新行。您将得到如下结果:

<div class="modal" tabindex="-1" role="dialog" aria-hidden="true">
  <div class="modal-dialog" style="width:auto;">
    <div class="modal-content">
      <div class="modal-body" style="margin-top: -25px;">
        <label id="LoadingRecord">1 of 5<br />2 of 5<br />3 of 5<br />4 of 5<br />5 of 5<br /></label>
      </div>
    </div>
  </div>
</div>

此外,&lt;label&gt; 元素没有value 属性。所以我们不能在那个元素或对象上使用.val()。我们可以使用.append()

更新

如果你想要一个进度条,这是一个非常不同的配置。这是一个基本的例子。

$(function() {
  var result = new Array(1000);
  var i = 0;

  function updateProgress(p) {
    console.log("Set progress to " + p + "%");
    $("#LoadingRecord .progress").css({
      "width": p + "%"
    });
  }

  // Once Array is loaded, can use setInterval to iterate it with timing
  // This example is using 100 MS
  var interval = setInterval(function() {
    // Increment counter
    ++i;
    updateProgress(Math.floor((i / result.length) * 100));
    // Check when to stop
    if (i >= result.length) {
      clearInterval(interval);
    }
  }, 100);
})
#LoadingRecord {
  border: 1px solid #ccc;
  width: 100%;
  height: 30px;
}

.progress {
  background-color: #ccf;
  height: 100%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
  <div class="modal" tabindex="-1" role="dialog" aria-hidden="true">
    <div class="modal-dialog">
      <div class="modal-content">
        <div class="modal-body">
          <div id="LoadingRecord">
            <div class="progress" style="width: 0;"></div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

如果你选择使用它,你可以简单地应用它,当你在循环中移动时,你会做同样的事情。 setInterval 仅在示例中用作循环,不会在您的代码中使用。

您将需要更新您的 HTML 以匹配上面的内容,然后像这样使用代码。

function updateProgress(p) {
  $("#LoadingRecord .progress").css({
    "width": p + "%"
  });
}

$.ajax({
  url: $("#GetAttendance").val(),
  type: "POST",
  dataType: "JSON",
  data: {
    StudentID: $("#StudentID").val()
  },
  success: function(result) {
    $.each(result, function(i, o) {
        updateProgress(Math.floor(((i + 1) / result.length) * 100));
        var row = $('#tableAttendance tbody>tr:last').clone(true);
        $('label[name="Date"]', row).val(o.Date);
        $('label[name="Presence"]', row).val(o.AbsentOrPresent);
        $('#tableAttendance tbody').append(row);
      }
    });
});

【讨论】:

  • 抱歉,是 .text()....... $("#LoadingRecord").text("正在加载" + (i+1) + " of " + result.length);
  • @LuciusFerdinand 如果您使用.text(),这将覆盖元素的文本内容。您将需要使用.append()
  • 是的,我需要覆盖以前的文本。如果前面的文本是“Loading 5 of 1000”,那么接下来就是“Loading 6 of 1000”。
  • 这是一个显示模式的进度条,显示循环的当前位置
  • 是的,这是我需要的。但我不知道如何将其添加到我的循环中
猜你喜欢
  • 1970-01-01
  • 2020-11-29
  • 1970-01-01
  • 2017-07-20
  • 1970-01-01
  • 2017-04-13
  • 2013-12-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多