Mulligan
Mulligan

Reputation: 210

Document.write method questions

I'm experimenting with write method & onload event. Here is my code:

<!DOCTYPE html>
<html>
    <head>
    </head>
    <body onload="document.write('body loaded!')">
        <h1>Hello World!</h1>
        <img onload="document.write('img loadeld!')" src="smiley.gif" alt="Smiley face" width="42" height="42" />
    </body>
</html>

If i run this in browser it outputs "img loadeld" and just "hangs", seems to be loading the page infinitely. I expected the browser outputs "img loadeld" and then as the body element is ready "body loaded" and just stops as normally.

My questions:

  1. Why is there such a hang? Why the onload event on img element blocks the browser from continuing & rendering "body loaded"?
  2. Why if i remove onload handler from img element the reponse is as expected - "body loaded" and the page isn't blocked.

Upvotes: 5

Views: 3969

Answers (5)

JAAulde
JAAulde

Reputation: 19550

Everything is working correctly (though not as you expected), and nothing is "hanging" or "blocking." It's all happening so fast, however, that it does not appear as such. Hopefully an explanation of the workings of writing to the document and the order of events will assist you:

Your IMG onload event fires after the document has been closed (document ready has been reached).

document.write(), however, can only output to an open document.

If a document has been closed, document.write() (docs) implicitly calls document.open() (docs) which wipes the entire document. Your call to write then outputs what you told it to. The document remains open until it is explicitly closed (document.close() (docs)), so the "loading spinner" continues to show.

The basic flow of operations, then, which is taking place (so quickly that you don't notice it all happening and things look broken) is:

  1. page request made
  2. page response received
  3. document is opened, content is parsed and put into place, including the first document.write (does not have to call open because document is currently open)
  4. document closes
  5. Retrieval for the IMG tag completes and the event fires
  6. event handler calls document.write
  7. document is implicitly re-opened (new doc created, all content lost; loading spinner displayed)
  8. your argument to document.write() is outputted into the new document
  9. everything is complete, document is still open

DOM manipulation techniques (appendChild(), writting to innerHTML, etc) should be used Instead of document.write in order to modify existing content without overwriting everything.

The good news in this is that since this is happening, you do know that your image is loading successfully. You just gotta work out the right way to react to it as I eluded to earlier.

Upvotes: 3

Alex Dn
Alex Dn

Reputation: 5553

When document.write used inside of function after html is loaded, it writes to new html document. onload is an event handler, so <img onload="document.write('img loadeld!')"/> = img.onload = function(event){document.write('img loadeld!');}.
It not blocks page loading, it just creates new blank html document.

Upvotes: 0

chrisfrancis27
chrisfrancis27

Reputation: 4536

Simply put, calling document.write() after DOM ready causes it to overwrite the existing DOM.

Upvotes: 3

Diodeus - James MacFarlane
Diodeus - James MacFarlane

Reputation: 114347

Create a message container, such as a DIV and set the innerHTML, don't use .write()

Upvotes: 0

Elias Van Ootegem
Elias Van Ootegem

Reputation: 76395

That's because document.write() clears the entire document, and then writes the argument to the page, try document.writeln('Img loaded'); to append to the body, but to stick to what you really want:

<img onload="document.body.innerHTML += '<h1>Loaded</h1>'"'

Or write a function that creates an element and use document.body.appendChild(elem), in which case you can replace document.body with any block element

Upvotes: 0

Related Questions