我想附加到一个元素并立即更新它。console.log()会按预期显示数据,但是append()在for循环完成之前不执行任何操作,然后立即将其全部写入。
index.html:
... <body> <p>Page loaded.</p> <p>Data:</p> <div id="Data"></div> </body>
test.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 } }); } });
server.php:
<?php sleep(1); echo time()."<br />"; ?>
直到for循环完成后,页面才呈现。在运行javascript之前,至少不应该首先呈现HTML吗?
如果您切换到async: true,则在添加数据时屏幕将能够更新。
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调用之间放置一小段时间,并且屏幕将在超时期间更新。
async: false
setTimeout()
还有一些黑客通过访问某些CSS属性“可能”导致屏幕更新(不保证),这些属性只能在HTML布局为最新时才计算,这可能导致浏览器显示最新更改。我之所以说“可能”,是因为这不是规范,而是对某些浏览器中行为的观察。您可以在此处阅读有关此选项的更多信息。
无论如何,由于您已经在使用ajax调用,因此解决此问题的最佳方法是使用async: true循环结构并将其更改为可用于异步ajax调用的结构(如我的示例所示)。