jQuery/Javascript -如何在继续执行函数之前等待被操纵的DOM更新
jQuery/Javascript - How to wait for manipulated DOM to update before proceeding with function
我要做的是在执行cpu密集型脚本(运行需要3-12秒,没有AJAX)之前更新一个简单的div以表示"Processing…",然后在完成时更新div以表示"Finished!"。
我看到的是div永远不会更新为"Processing…"。如果我在该命令之后立即设置一个断点,那么div文本就会得到更新,这样我就知道语法是正确的。在IE9, FF6, Chrome13中也有相同的行为。
即使绕过jQuery而使用基本的原始Javascript,我也会看到同样的问题。
你会认为这个问题的答案很简单。但是,由于jQuery .html()和.text()没有回调钩子,所以这不是一个选项。它也不是动画的,所以没有。queue可以操作。
您可以使用我在下面准备的示例代码来测试这一点,该示例代码显示了jQuery和Javascript实现的5秒高cpu函数。代码很容易理解。当您单击按钮或链接时,您永远不会看到"Processing…"
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js" ></script>
<script type="text/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');
});
});
</script>
</head>
<body>
<div id="msg">Not Started</div>
<button>jQuery</button>
<a href="#" onclick="doRun()">javascript</a>
</body>
</html>
将其设置为正在处理,然后执行setTimeout以防止cpu密集型任务在更新div之前运行。
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js" ></script>
<script>
function addSecs(d, s) {return new Date(d.valueOf()+s*1000);}
function doRun() {
document.getElementById('msg').innerHTML = 'Processing JS...';
setTimeout(function(){
start = new Date();
end = addSecs(start,5);
do {start = new Date();} while (end-start > 0);
document.getElementById('msg').innerHTML = 'Finished Processing';
},10);
}
$(function() {
$('button').click(doRun);
});
</script>
</head>
<body>
<div id="msg">Not Started</div>
<button>jQuery</button>
<a href="#" onclick="doRun()">javascript</a>
</body>
</html>
你可以根据需要修改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让浏览器在执行你的函数之前有机会渲染:
$(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/我必须等待jQuery操作DOM,然后捕获更改(将表单字段多次加载到表单中,然后提交它)。DOM不断增长,插入所花费的时间越来越长。我使用ajax保存更改,以便用户能够继续他离开的地方。
This did NOT WORK如预期:
jQuery('.parentEl').prepend('<p>newContent</p>');
doSave(); // wrapping it into timeout was to short as well sometimes
由于像.prepend()
这样的jQuery函数只在完成后才继续链,下面的似乎可以做到:
jQuery('.parentEl').prepend('<p>newContent</p>').queue(function() {
doSave();
});
截至2019年,人们使用double requesAnimationFrame
来跳过一帧,而不是使用setTimeout创建竞争条件。
....
function doRun() {
document.getElementById('msg').innerHTML = 'Processing JS...';
requestAnimationFrame(() =>
requestAnimationFrame(function(){
start = new Date();
end = addSecs(start,5);
do {start = new Date();} while (end-start > 0);
document.getElementById('msg').innerHTML = 'Finished Processing';
}))
}
...
- 单击按钮以等待单击按钮
- React组件等待所需道具进行渲染
- 正在等待呈现图表,直到加载数据为止
- 在等待ajax请求时显示微调器并禁用页面
- Javascript在for循环中等待处理请求
- JavaScript循环并等待函数
- 在等待异步任务时永久循环
- 在通过child.print()打印之前,我如何等待图像加载到我的新窗口中
- 用于操纵DOM API的Javascript设计模式
- 失败:等待Protractor与页面同步时出错:“”;在窗口上找不到角度”;
- 等待300毫秒,然后使用jQuery向下滑动菜单
- 等待循环调用的所有承诺完成
- 等待回调函数执行
- RxJS等待承诺解决
- WIll window.addEventListener(“加载”,function(),false);等待浏览器自动填
- webgl在一个正方形上操纵两个纹理
- Casperjs等待资源
- draggableCursor没有't更改为等待光标
- 如何使请求等待上一个请求完成
- jQuery/Javascript -如何在继续执行函数之前等待被操纵的DOM更新