views:

54

answers:

3

I have the test code below. I was expecting Firefox to display the first image, execute the delay and suspend the retrieval of the second image then display "Hello" and the second image.

Why is it displaying everything at once after the delay?

UPDATE: I need to add more clarification. I am NOT trying to write production code. I read that a browser would suspend execution of a js script until it's done and then continue displaying whatever is present after the script tag. This includes retrieving images on the other browser connections. I am trying to prove that's what actually happens and it's not.

<body>
<img src="images/web.gif" /><br />
<script type="text/javascript">
  document.body.innerHTML = "";
  for (var i = 0; i < 1000000000; i++) {
  }
  document.write( "hello<br />");
</script>
<img src="images/web2.gif" /><br />
</body>
A: 

With all respect...using such a loop as a timer is a violation of everything I believe in! (I don't know if here should be a winking smiley...because I mean that but it's not an insult on you)

There is a timer-object in JavaScript, there are several plugins for jQuery, please use one of them. Because Firefox is most likely either optimizing the loop to nothing or executing it pretty fast.

Edit: On second thought, Firefox is most likely loading the whole document first before executing JavaScript.

Bobby
His question wasn't about the delay...
Killroy
It still doesn't hurt to point out that this is an atrocious thing to do -- although better suited to being a comment on the main question rather then an answer.
Erik
@Killroy: His question is about the delay. And as I stated, I think Firefox is either optimizing that loop to nothing, executing it way too fast or loading the whole document first before executing JavaScript (hey, I'm gonna edit that in).
Bobby
+2  A: 

Well, inlining a document.write in a script part actually makes the browser interpret that straight away since you may output various things there, including for example a comment start (<!--) which would invalidate the rest.

If you want to avoid the Javascript execution blocking the page load you should use an external file and the defer attribute. This will tell the browser that this script does not need to be interpreted straight away so the browser can continue rendering the page:

<script type="text/javascript" src="delay.js" defer="defer"></script>

However, if you do that you will not be able to inline your output with document.write like you did in your example. But that should not be a problem. You can add a at the same location and have the following in your script.

document.getElementById("output").innerHTML = "Hello";

Furthermore, if you use defer on a script then your script's variables will not be available straight away for other non-deferred script blocks in your app (for obvious reasons, they may not be loaded yet!).

Second, don't use a loop to emulate a delay. I can't stress how bad that is. I assume you used it just for the sake of simplicity.

Sorin Mocanu
A: 

Here's a way to get done what you want; I'm using the jQuery library to make it easier so I've included the statement to load that as well, from Google!

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"&gt;&lt;/script&gt;
<script>
  // This won't execute until the page has actually loaded
  $(document).ready(function() {   
    // The number is miliseconds; in this case a 5 sec wait
    // and the text is the name of the function to call.
    window.setTimeout(addImage,5000);
  });

  function addImage() { 
     $('body').append('<img src="book.jpg" />');
  }
</script>

This accomplishes your goal. After the page is loaded, it will wait 5 seconds (or whatever time you specify) and then it will add the second image (on my desktop I used the same image twice, in order to verify this worked properly).

Erik
See my update. I need to run the script while the page is loading.
Tony_Henrich