99

I have this HTML code:

<html>
  <head>
    <script type="text/javascript">
      function GetDoc(x)
      {
        return x.document ||
          x.contentDocument ||
          x.contentWindow.document;
      }

      function DoStuff()
      {
        var fr = document.all["myframe"];
        while(fr.ariaBusy) { }
        var doc = GetDoc(fr);
        if (doc == document)
          alert("Bad");
        else 
          alert("Good");
      }
    </script>
  </head>
  <body>
    <iframe id="myframe" src="http://example.com" width="100%" height="100%" onload="DoStuff()"></iframe>
  </body>
</html>

The problem is that I get message "Bad". That mean that the document of iframe is not got correctly, and what is actualy returned by GetDoc function is the parent document.

I would be thankful, if you told where I do my mistake. (I want to get document hosted in IFrame.)

Thank you.

Nicolas Raoul
  • 58,567
  • 58
  • 222
  • 373
ernestasju
  • 1,319
  • 1
  • 11
  • 14
  • 8
    This was asked in 2010, today in 2015, this would not work in any newer browser, unless you are developing to google.com. Because of cross origin policy, you cannot access the content of the iframe, if it points to a page on a different domain than the one your original document is loaded from. – aorcsik Nov 05 '15 at 22:50
  • if anyone need to Access elements of parent window from iframe, see https://stackoverflow.com/questions/7027799/access-elements-of-parent-window-from-iframe – yu yang Jian Feb 08 '22 at 06:55

4 Answers4

198

You should be able to access the document in the IFRAME using the following code:

    document.getElementById('myframe').contentWindow.document

However, you will not be able to do this if the page in the frame is loaded from a different domain (such as google.com). This is because of the browser's Same Origin Policy.

unrealapex
  • 578
  • 9
  • 23
pkaeding
  • 36,513
  • 30
  • 103
  • 141
  • 4
    Huh? That will return either `undefined` (most browsers) or the document that the ` – Tim Down Oct 22 '10 at 17:30
  • Oops, I guess that's what I get for not testing it first :-/. I just edited it to add the contentWindow reference. – pkaeding Oct 22 '10 at 18:34
  • 23
    note that `iframe.contentDocument == iframe.contentWindow.document` – destan Sep 28 '13 at 14:14
  • https://stackoverflow.com/a/9393545/19068 is worth a look if you do need to deal with this across origins. – Quentin Jun 30 '23 at 10:09
18

The problem is that in IE (which is what I presume you're testing in), the <iframe> element has a document property that refers to the document containing the iframe, and this is getting used before the contentDocument or contentWindow.document properties. What you need is:

function GetDoc(x) {
    return x.contentDocument || x.contentWindow.document;
}

Also, document.all is not available in all browsers and is non-standard. Use document.getElementById() instead.

Tim Down
  • 318,141
  • 75
  • 454
  • 536
4

In case you get a cross-domain error:

If you have control over the content of the iframe - that is, if it is merely loaded in a cross-origin setup such as on Amazon Mechanical Turk - you can circumvent this problem with the <body onload='my_func(my_arg)'> attribute for the inner html.

For example, for the inner html, use the this html parameter (yes - this is defined and it refers to the parent window of the inner body element):

<body onload='changeForm(this)'>

In the inner html :

    function changeForm(window) {
        console.log('inner window loaded: do whatever you want with the inner html');
        window.document.getElementById('mturk_form').style.display = 'none';
    </script>
Zhanwen Chen
  • 1,295
  • 17
  • 21
1

You can also use:

document.querySelector('iframe').contentDocument
double-beep
  • 5,031
  • 17
  • 33
  • 41
Ahmed Yasser
  • 109
  • 12