我已经定义了在Web文档准备就绪时执行的函数中有一系列Javascript函数调用。我期望它们按顺序执行,因为一个结束下一个开始,但我看到的行为与之不符。
此外,在调用之间还有对图形组件的操作(例如,我在每个提到的调用之间添加一个检查点时间来绘制页面上的div)但是这些重绘不会发生在顺序......它们都是一次性发生的。
我对浏览器中的整个javascript有点n00b,我正在制作一个明显的错误,还是一个很好的资源去了解如何做这些东西?
更新 - 样本
// called onReady()
function init() {
doFirstThing();
updateDisplayForFirstThing();
doSecondThingWithAjaxCall();
updateDisplayForSecondThing();
...
reportAllLoaded();
}
答案 0 :(得分:1)
在当前脚本运行完毕之前,IE不会更新显示。如果要在一系列事件中重绘,则必须使用超时来破坏脚本。
如果您发布一些代码,我们可以帮助重构它。
编辑:这是一个普遍的模式。
function init() {
doFirstThing();
updateDisplayForFirstThing();
}
function updateDisplayForFirstThing() {
// existing code
...
// prepare next sequence
var nextFn = function() {
// does this method run async? if so you'll have to
// call updateDisplayForSecondThing as a callback method for the
// ajax call rather than calling it inline here.
doSecondThingWithAjaxCall();
updateDisplayForSecondThing();
}
setTimeout(nextFn, 0);
}
function updateDisplayForSecondThing() {
// existing code
...
// prepare next sequence
var nextFn = function() {
// continue the pattern
// or if you're done call the last method
reportAllLoaded();
}
setTimeout(nextFn, 0);
}
答案 1 :(得分:1)
对于许多情况,可以使用回调修复此问题,尤其是使用AJAX调用时 - 例如:
function doFirstThing(fn){
// doing stuff
if(typeof fn == 'function') fn();
}
function updateDisplayForFirstThing(){
// doing other stuff
}
function init(){
doFirstThing(updateDisplayForFirstThing);
}
另一种选择是使用返回值:
function doFirstThing(fn){
// doing stuff
if(x) return true;
else return false;
}
function updateDisplayForFirstThing(){
// doing other stuff
return true;
}
function init(){
if(doFirstThing()){ updateDisplayForFirstThing(); }
}
设置超时以逐步执行代码并不是解决此问题的好方法,因为您必须将每个代码执行时可能需要的最长时间设置为超时。
但是,您有时可能需要使用setTimeout
来确保在某些操作后DOM已正确更新。
答案 2 :(得分:1)
如果您最终决定要使用某种JavaScript线程,请查看仍在起草的Web Workers API。尽管API已在大多数现代Web浏览器中实现,但浏览器支持仍然受到欢迎。
问题:你究竟是怎么决定“doc准备好了”的? IE中不支持DOMContentLoaded事件我非常肯定...如果您需要等待文档全部加载,可以使用以下内容:
var onReady = function(callback) {
if (document.addEventListener) {
document.addEventListener("DOMContentLoaded", callback, false);
return true;
} else if (document.attachEvent) {
var DOMContentLoaded = function() {
if (document.readyState === "complete") {
document.detachEvent("onreadystatechange", DOMContentLoaded);
onReady();
}
};
return true;
}
};
然后当然你需要为一些标志状态开发一个setTimeout测试,指示页面在完成后加载,然后继续执行其余的代码...那个或任意数量的其他方法... < / p>
或者您可以将脚本包含在身体的底部......
我只是漫无目的,直到你有一些代码向我们展示?