代码之家  ›  专栏  ›  技术社区  ›  NGM

使用ajax更新元素直到for循环结束才生效

  •  5
  • NGM  · 技术社区  · 7 年前

    我想用AJAX一个接一个地打印很多数字。

    类似这样:(每一行都是前一行的更新!)

    output is:
        1
        12
        123
        1234
        12345
        123456
        ...
    

    我试了很多次,读了很多同样的问题,但我找不到正确的答案。

    真正的问题是javascript中的每个FOR循环在结束循环后都不会影响DOM。我只想在处理长时间运行的作业时更新FOR循环中的DOM。

    请看我的代码。

    $("#btn").on("click", dowork);
    
    function dowork() {
      document.getElementById("foo").innerHTML = "working";
      setTimeout(function() {
        var counter = 100; // i want assign counter = 2000000000
        for (var i = 0; i < counter; i++) {
          document.getElementById("print_here").innerHTML += i;
        }
        document.getElementById("foo").innerHTML = "done!";
      }, 50);
    }
    #btn {
      background: #1f1f1f;
      padding: 10px;
      font-weight: bolder;
      color: #fff;
      width: 50%;
      margin: auto;
      margin-top: 10px;
      text-align: center;
      cursor: pointer;
    }
    
    #print_here {
      overflow-wrap: break-word;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div id="btn">CLICK TO DO WORK</div>
    <div id="foo"></div>
    <div id="print_here"></div>

    感谢您的回答和帮助,以解决此问题。

    3 回复  |  直到 7 年前
        1
  •  6
  •   Nope landerton    7 年前

    DOM在更新和重画时处于“锁定”状态,循环完成后即处于锁定状态。您可以释放资源,以便在每次将DOM更改包装到 setTimeout ,类似于:

    setTimeout(function(){
        document.getElementById("print_here").innerHTML += i;
    },1);
    

    确保 设置超时 使用正确的值 i 使用 let i 而不是 var i

    $("#btn").on("click", dowork);
    
    function dowork() {
      document.getElementById("foo").innerHTML = "working";
    
      var counter = 3000; // i want assign counter = 2000000000
      for (let i = 0; i < counter; i++) {
        setTimeout(function() {
          document.getElementById("print_here").innerHTML += i;
        }, 1);
      }
      document.getElementById("foo").innerHTML = "done!";
    }
    #btn {
      background: #1f1f1f;
      padding: 10px;
      font-weight: bolder;
      color: #fff;
      width: 50%;
      margin: auto;
      margin-top: 10px;
      text-align: center;
      cursor: pointer;
    }
    
    #print_here {
      overflow-wrap: break-word;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div id="btn">CLICK TO DO WORK</div>
    <div id="foo"></div>
    <div id="print_here"></div>

    我想将#foo改为“完成!”FOR语句结束后

    您可以检查您是否在 设置超时 ,类似于:

    if (i == counter - 1){
        document.getElementById("foo").innerHTML = "done!";
    }
    

    $("#btn").on("click", dowork);
    
    function dowork() {
      document.getElementById("foo").innerHTML = "working";
    
      var counter = 3000; // i want assign counter = 2000000000
      for (let i = 0; i < counter; i++) {
        setTimeout(function() {
          document.getElementById("print_here").innerHTML += i;
          if (i == counter - 1){
            document.getElementById("foo").innerHTML = "done!";
          }
        }, 1);
      }
    }
    #btn公司{
    背景:#1f1f1f;
    填充:10px;
    字体大小:加粗;
    颜色:#fff;
    宽度:50%;
    边距:自动;
    边缘顶部:10px;
    文本对齐:居中;
    光标:指针;
    }
    
    #在此处打印\u{
    溢出换行:断开单词;
    }
    <脚本src=”https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js“></script>
    <div id=“btn”>单击以执行工作(</div>
    <div id=“foo”></div>
    <div id=“此处打印”></div>
        2
  •  1
  •   Brad    7 年前

    您需要让调用堆栈完成,以便浏览器可以在页面上执行其工作。如果您陷入一个主线程的困境,页面更新就不会发生。

    一种方法是使用setImmediate或nextTick。这是非标准的,因此请检查此polyfill: https://www.npmjs.com/package/browser-next-tick

    基本上,您先进行一次迭代,然后告诉浏览器尽快进行下一次迭代。。。这发生在一个新的调用堆栈上。

        3
  •  -2
  •   garfbradaz Vivek    7 年前

    以下是您的工作代码:

    $("#btn").on("click", dowork);
    
    function dowork() {
      document.getElementById("foo").innerHTML = "working";
      setTimeout(function() {
    
        var i, j, row = 5;
        var html = "";
        for (i = 1; i <= row; i++) {
          for (j = 1; j <= i; j++) {
            html += "<span>" + j + "</span>";
          }
          html += "</br>";
        }
        console.log(html);
        document.getElementById("print_here").innerHTML = html;
      }, 50);
    }
    #btn {
      background: #1f1f1f;
      padding: 10px;
      font-weight: bolder;
      color: #fff;
      width: 50%;
      margin: auto;
      margin-top: 10px;
      text-align: center;
      cursor: pointer;
    }
    
    #print_here {
      overflow-wrap: break-word;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div id="btn">CLICK TO DO WORK</div>
    <div id="foo"></div>
    <div id="print_here"></div>

    要打印的行数。