2

I am trying to understand importNode in html using the following example.

Suppose we have a content.html:

<html>
  <body>
    <nav id="sidebar1" class="sidebar">
       Hi there!
    </nav>
  </body>
</html>

and a main.html:

<html>
  <body>
    <iframe src='content.html' hidden='true'></iframe>
    <script>
      var idframe = document.getElementsByTagName("iframe")[0];
      var oldNode = idframe.contentWindow.document.getElementsByTagName("nav")[0];
      var newNode = document.importNode(oldNode, true);
      document.getElementsByTagName("body")[0].appendChild(newNode);
      alert("HI!!!");
    </script>
  </body>
</html>

I am getting the error:

TypeError: Argument 1 of Document.importNode is not an object.
var newNode = document.importNode(oldNode, true);

What is the proper way to get an element form an iframe and insert it into my html?

beginner123
  • 105
  • 6

1 Answers1

1

You can only access content of the iframe document after the iframe document has been loaded. This can be accomplished different ways:

  • either by putting your accessing code into load handler of the main (that contains iframe element) document window,
  • or inside a DOMContentLoaded event listener of the document loaded in iframe.

Below is example of using load event of window of the main document:

window.addEventListener('load', function() {
    var iframe = document.getElementsByTagName("iframe")[0];
    var oldNode = iframe.contentWindow.document.getElementById("myNode");
    var newNode = document.importNode(oldNode, true);
    document.body.insertBefore(newNode, document.body.firstChild);
}, false);

Otherwise, iframe content is not yet loaded when you try to access it.

See the live example at JSFiddle (iframe content is placed encoded in the srcdoc attribute of the iframe just because I'm not aware of ability to create subdocuments at JSFiddle without creating a separate fiddle).

Marat Tanalin
  • 13,927
  • 1
  • 36
  • 52
  • Let me see if I understand what you are saying. There is a tricky business about when the iframe is loaded and when the javascript is executed. Right? So, I should place the JavaScript at some point that is executed after the iframe. Is this correct? I am not completely sure if you mean that the position of the `` is relevant. I put the event `window.addEventLis...` inside a `` inside the body, after the `iframe`. Is this correct? – beginner123 Oct 03 '15 at 17:35
  • It works now. Thanks. But I would like to also understand what was the key change. 1) position of the ``? 2) The fact that the code is inside an event listener, which is executed after the page has loaded? 3) Both combined? – beginner123 Oct 03 '15 at 17:36
  • 1
    It should typically not matter where to put the code that adds `load` event listener (the listener will anyway be called _after_ the document is completely loaded), but it's usually placed inside `HEAD` element (either as JS code or as a link to an external script like ``). – Marat Tanalin Oct 03 '15 at 17:44
  • Got it. Thanks. Is this a standard way to delay the importNode, adding it in an event? Seems to be that taking html into html is cumbersome. – beginner123 Oct 03 '15 at 18:01
  • Yes, it is a common practice to use `DOMContentLoaded` of `document` (when just HTML and CSS need to be loaded) and `load` of `window` (when all page resources need to be loaded) for waiting until the page content or its embedded resources are ready to be used. As for frames in particular, they are generally unneeded if what you really need is retrieving some data from the server; [`XMLHttpRequest`](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest) is a more modern, usable and preferred way for this. – Marat Tanalin Oct 03 '15 at 18:48
  • Thank you for pointing me in the right direction.There seem to be many ways to manipulate webpages and it can be overwhelming the different tools one can use to do the same thing. I am trying to get a side navigation bar for all the webpages in a mock website. That is why I am trying to import html (the navigation bar) into another. – beginner123 Oct 03 '15 at 19:15