【问题标题】:manipulate text of an element in $each function在 $each 函数中操作元素的文本
【发布时间】:2023-03-14 02:10:01
【问题描述】:

我正在尝试以百分比为用户显示 $each 循环中对象的传递。 在控制台中,我看到了正确的值,但在前端,直到 $each 循环完成后才会显示项目的内容,然后显示 100%。

<div id="editForm-loader">
   <p><i class="fas fa-spinner fa-pulse"></i> Daten werden geladen <i class="info"></i> <input type="text" value="" class="info"></p>
</div>



success: function(response) {
  var aData   = JSON.parse(response).data;
  var count   = 0;
  var loading = 0;
  var rows    = Object.keys(aData).length;
  $.each(aData, function(key, value) {
    count++;
    loading = Math.round((count*100)/rows);
    $('#editForm-loader i.info').text(loading + '%');      // nothing changes in the frontend 
    $('#editForm-loader input.info').val(progress + '%');  // to test, but also does not change
    console.log($('#editForm-loader i.info').text());      // show the correct value

    // at this point I do a lot with the data
    // so the each function with over 100 items takes about 5 seconds total.

  });
  $('#editForm-loader').hide();
}

应该在 ajax 成功回调中执行的提示

好像渲染被及时阻塞了

[已解决]

success: function(response) {
  var aData     = JSON.parse(response).data;
  var count     = 0;
  var loading   = 0;
  var items     = Object.keys(aData).length;
  var aFields   = [];
  for (var key in aData) {
    aFields.push({'key': key,   'val': aData[key]});    // It is an assoc array, so I am writing it again to be able to access it with count.
  }

  var iV  = setInterval(function() {
    loading  = Math.round(((count+1)*100)/items);
    $('#editForm-loader i.info').text(loading + '%');
    var key   = aFields[count].key;
    var value = aFields[count].val;

    // at this point I do a lot with the data
    // so the each function with over 100 items takes about 5 seconds total.

    if (++count >= items) {
      clearInterval(iV);
      $('#editForm-loader').hide();
    }
  }, 0);
}

【问题讨论】:

  • 可能循环只运行几毫秒?一个代码 sn-p 会很好
  • 我再次扩展了我的代码。它运行了大约 5 秒,在控制台中我准确地看到了 % 值,看起来不错。当我查询元素的内容时,它看起来也很不错。只是对用户不可见。
  • hmn 对我来说这真的很难回答,因为我不知道如何重现它。也许您可以尝试将 .text() 替换为 vanilla js,例如 $('#editForm-loader i.info')[0].textContent = loading+'%' 以验证它实际上是 jquery 或其他问题的问题
  • 你好@johnSmith,谢谢你的提示,我已经测试过了,不幸的是它也不起作用。
  • 我想说原因仍然是循环只需要几毫秒,并且由于 js 的异步特性,您可以想象看到控制台日志应该是这样的,这真的取决于什么是“我对这些数据做了很多事情”

标签: jquery progress-bar each


【解决方案1】:

您可以使用setTimeout() 并在每次循环迭代时增加延迟。

简化示例:

const data = [10, 30, 50, 70, 90, 100]

$.each(data, function(i, value) {
  setTimeout(function() {    
    $('#editForm-loader i.info').text(value + '%');
  }, i * 500)// 1/2 second increments
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p id="editForm-loader"><i class="info"></i></p>

【讨论】:

  • 感谢您的回答,但不幸的是,setTimeout 没有帮助。在您的示例中,元素也仅在对象完全通过时才更新,而不是在每个项目之后更新。示例对象有 50 个项目。然后一个 2% 之后应该显示两个 4% 之后三个 6% 等等。
猜你喜欢
  • 1970-01-01
  • 2020-08-21
  • 1970-01-01
  • 2021-07-01
  • 2018-08-31
  • 1970-01-01
  • 2018-05-12
  • 1970-01-01
  • 2012-09-10
相关资源
最近更新 更多