开发者

How to control Javascript threading and redrawing in IE7

开发者 https://www.devze.com 2023-01-22 02:13 出处:网络
I\'ve got a sequence of Javascript function calls in a function I have defined to be executed when a web doc is ready. I expected them to be executed in sequence, as one ends the next begins, but the

I've got a sequence of Javascript function calls in a function I have defined to be executed when a web doc is ready. I expected them to be executed in sequence, as one ends the next begins, but the behaviour I see doesn't match up with that.

Additionally there is manipulation of the graphical components going on in between the calls (for example, I add in a checkpoint time to draw on a div on the page inbetween each of the mentioned calls) but those redraws aren't happening in sequence... they all happen at once.

I'm a bit of a n00b with the whole javascript-in-the-browser thing, is there an obvious mistake I'm making, or a good resource to go 开发者_如何学Gofind out how to do this stuff?


Update - sample

// called onReady()
function init() {
    doFirstThing();
    updateDisplayForFirstThing();
    doSecondThingWithAjaxCall();
    updateDisplayForSecondThing();
    ...
    reportAllLoaded();
}


IE won't update the display until the current script is finished running. If you want to redraw in the middle of a sequence of events, you'll have to break your script up using timeouts.

If you post some code we can help refactor it.

edit: here's a general pattern to follow.

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);
}


This can be fixed for many cases by using callbacks, especially with AJAX calls -- for example:

function doFirstThing(fn){
  // doing stuff
  if(typeof fn == 'function') fn();
}

function updateDisplayForFirstThing(){
  // doing other stuff
}

function init(){
  doFirstThing(updateDisplayForFirstThing);
}

Another option is to use return values:

function doFirstThing(fn){
  // doing stuff
  if(x) return true;
  else return false;
}

function updateDisplayForFirstThing(){
  // doing other stuff
  return true;
}

function init(){
  if(doFirstThing()){ updateDisplayForFirstThing(); }
}

setting timeouts to step through your code is not really a good way to fix this problem because you'd have to set your timeouts for the maximum length of time each piece of code could possibly take to execute.

However, you may still sometimes need to use a setTimeout to ensure the DOM has properly updated after certain actions.


If you end up deciding that you would like some JavaScript threading, check out the still being drafted Web Workers API. Browser support is hit and miss though the API is implemented in most modern web browsers.

Question: exactly how did you go about determining when the "doc is ready"? The DOMContentLoaded event isn't supported in IE I'm fairly certain... if you're in need of waiting for your document to load in its entirety you could use something like this:

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;
    }
};

Then of course you'll need to develop a setTimeout testing for some flags state indicating the page is loaded upon completion before continuing the execution of the rest of your code... that or any number of other methods...

Or you could just include the script at the bottom of your body...

I'm just rambling though until you have some code to show us?

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号