`ImportNode` in Firefox and extracting an element

2019-07-12 17:47发布

问题:

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?

回答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).