3

我想附加到一个元素并立即更新它。console.log() 按预期显示数据,但 append() 在 for 循环完成之前什么都不做,然后一次将其全部写入。

索引.html:

...
<body>
    <p>Page loaded.</p>
    <p>Data:</p>
    <div id="Data"></div>
</body>

测试.js:

$(document).ready(function() {
    for( var i=0; i<5; i++ ) {
        $.ajax({
            async: false,
            url: 'server.php',
            success: function(r) {
                console.log(r); //this works
                $('#Data').append(r); //this happens all at once

            }
        });
    }
});

服务器.php:

<?php 
    sleep(1);
    echo time()."<br />";
?>

在 for 循环完成之前,页面甚至不会呈现。它不应该至少在运行 javascript 之前先渲染 HTML 吗?

4

1 回答 1

4

如果您切换到async: true,则屏幕将能够在您追加数据时更新。

$(document).ready(function() {
    var cntr = 0;
    // run 5 consecutive ajax calls
    // when the first one finishes, run the second one and so on
    function next() {
        $.ajax({
            async: true,
            url: 'server.php',
            success: function(r) {
                console.log(r); //this works
                $('#Data').append(r); //this happens all at once
                ++cntr;
                if (cntr < 5) {
                    next();
                }

            }
        });
    }
    next();
});

如果您坚持使用async: false(这通常很糟糕),那么您可以setTimeout()在每个 ajax 调用之间放置一个短路,并且屏幕会在超时期间更新。

还有一些黑客“可能”通过访问某些 CSS 属性来“可能”导致屏幕更新(不保证),这些属性只能在 HTML 布局是最新的时计算,这可能会导致浏览器显示最新的更改。我说“可能”是因为这不是规范,只是对某些浏览器中行为的观察。您可以在此处阅读有关此选项的更多信息。

无论如何,由于您已经在使用 ajax 调用,因此解决此问题的最佳方法是使用async: true循环构造并将其更改为可与异步 ajax 调用一起使用的循环构造(如我在示例中所示)。

于 2013-10-31T03:50:05.040 回答