jQuery / Javascript – 如何在继续执行函数之前等待被操作的DOM更新

我要做的是在执行CPU密集型脚本之前更新一个简单的div来说“Processing …”(运行需要3-12秒,没有AJAX)然后更新div来说“完成! “ 完成后。

我所看到的是div永远不会更新“Processing …”。 如果我在该命令后立即设置断点,那么div文本会更新,所以我知道语法是正确的。 IE9,FF6,Chrome13中的行为相同。

即使绕过jQuery并使用基本的原始Javascript,我也看到同样的问题。

你认为这会有一个简单的答案。 但是,由于jQuery .html()和.text()没有回调挂钩,因此这不是一个选项。 它也没有动画,所以没有.queue可以操纵。

你可以使用我在下面编写的示例代码来测试这个,它显示了具有5秒高CPUfunction的jQuery和Javascript实现。 代码很容易理解。 当您单击按钮或链接时,您永远不会看到“正在处理…”

     function addSecs(d, s) {return new Date(d.valueOf()+s*1000);} function doRun() { document.getElementById('msg').innerHTML = 'Processing JS...'; start = new Date(); end = addSecs(start,5); do {start = new Date();} while (end-start > 0); document.getElementById('msg').innerHTML = 'Finished JS'; } $(function() { $('button').click(function(){ $('div').text('Processing JQ...'); start = new Date(); end = addSecs(start,5); do {start = new Date();} while (end-start > 0); $('div').text('Finished JQ'); }); });    
Not Started
javascript

将其设置为处理,然后执行setTimeout以防止cpu密集型任务运行,直到更新div为止。

        
Not Started
javascript

你可以根据需要修改setTimeout延迟,对于较慢的机器/浏览器,它可能需要更大。

编辑:

您还可以使用警报或确认对话框来更新页面时间。

 document.getElementById('msg').innerHTML = 'Processing JS...'; if ( confirm( "This task may take several seconds. Do you wish to continue?" ) ) { // run code here } 

您有一个运行5秒的循环,并在此期间冻结Web浏览器。 由于Web浏览器被冻结,因此无法进行任何渲染。 你应该使用setTimeout()而不是循环,但我假设循环只是一个需要一段时间的CPU密集型函数的替代品? 在执行函数之前,您可以使用setTimeout为浏览器提供渲染的机会:

jQuery的:

 $(function() { $('button').click(function(){ (function(cont){ $('div').text('Processing JQ...'); start = new Date(); end = addSecs(start,5); setTimeout(cont, 1); })(function(){ do {start = new Date();} while (end-start > 0); $('div').text('Finished JQ'); }) }); }); 

香草JS:

 document.getElementsByTagName('a')[0].onclick = function(){ doRun(function(){ do {start = new Date();} while (end-start > 0); document.getElementById('msg').innerHTML = 'Finished JS'; }); return false; }; function doRun(cont){ document.getElementById('msg').innerHTML = 'Processing JS...'; start = new Date(); end = addSecs(start,5); setTimeout(cont, 1); } 

您还应该记住始终使用var关键字声明所有变量,并避免将它们暴露给全局范围。 这是一个JSFiddle:

http://jsfiddle.net/Paulpro/ypQ6m/