1

I'm new to JavaScript and HTML5 and today I was playing with createHTMLDocument() and I ran into a frustrating problem. I got the following snippet from Mozilla's site:

<script>
   function makeDocument() {
   var frame = document.getElementById("theFrame");

   var doc = document.implementation.createHTMLDocument("New Document");
   var p = doc.createElement("p");
   p.innerHTML = "This is a new paragraph.";

   try {
     doc.body.appendChild(p);
   } catch(e) {
     console.log(e);
   }

   var destDocument = frame.contentDocument;
   var srcNode = doc.documentElement;
   var newNode = destDocument.importNode(srcNode, true);

   destDocument.replaceChild(newNode, destDocument.documentElement);
   console.log(destDocument.readyState);
}
</script>
<body>
  <p>Click <a href="javascript:makeDocument()">here</a> to create a new document and insert it below.</p>
  <iframe id="theFrame" src="about:blank" />
</body>

It works as expected. The text is put into the doc and the expected readyState, "complete", is written to the console.

But then I rejiggered the code so that makeDocument ran automatically on load, like so:

<div>
  <iframe id="frame" src="about:blank"> </iframe>
</div>

<script>
  function makeDocument() {
    var frame = document.getElementById("frame");

    var doc = document.implementation.createHTMLDocument("New Document");
    var p = doc.createElement("p");
    p.innerHTML = "This is a new paragraph.";

    try {
      doc.body.appendChild(p);
  } catch(e) {
      console.log(e);
    }

    var destDocument = frame.contentDocument;
    var srcNode = doc.documentElement;
    var newNode = destDocument.importNode(srcNode, true);

    destDocument.replaceChild(newNode, destDocument.documentElement);
    console.log(destDocument.readyState);
  }

  makeDocument();
</script>

But when this is run the text is not added to the document and the document's readyState is "uninitialized." I'm sure I'm making some stupid mistake. Any ideas?

P Jones
  • 1,077
  • 1
  • 9
  • 14

1 Answers1

1

If you want to call a javascript function that manipulates the DOM you should use an onload event handler.

Try adding

<body onload="makeDocument()">

instead of calling the function directly in your script tag.

Browsers are multi-threaded so you cannot guarantee that the DOM is done loading even though the script tag is after the iframe definition.

lukevp
  • 705
  • 4
  • 16
  • 1
    Yup, that did it. Thanks. Though I'm still confused. I also tried `window.onload = makeDocument();` which seems like it should work (but didn't), since the [spec](https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers.onload) says that `window.onload` fires only after all of the objects are in the DOM and all other resources have loaded. – P Jones Jan 17 '15 at 05:35
  • sorry for taking a few days to get back to you over the weekend. the reason your window.onload = makeDocument(); statement is failing is because by putting the parenthesis, you are telling Javascript to call the function right then, and then assign the return value to the onload. What you really want to do is assign the function itself to the onload, and your function will be called when the event fires, like this: window.onload = makeDocument; Thanks for accepting my answer, please upvote it as well if you get a chance! – lukevp Jan 19 '15 at 15:54
  • Thanks for getting back. I made a second question addressing that issue and someone else answered. Totally obvious in retrospect. – P Jones Jan 20 '15 at 20:21
  • And I cannot upvote your answer as yet. But I will ass soon as I get enough points. – P Jones Jan 20 '15 at 20:21