views:

300

answers:

2

I'm trying to figure out the best way to access an <iframe> element's window and document properties from a parent page. The <iframe> may be created via JavaScript or accessed via a reference stored in an object property or a variable, so, if I understand correctly, that rules out the use of document.frames.

I've seen this done a number of ways, but I'm unsure about the best approach. Given an <iframe> created in this way:

var iframe = document.createElement('iframe');
document.getElementsByTagName('body')[0].appendChild(iframe);

I'm currently using this to access the document, and it seems to work OK across the major browsers:

var doc = iframe.contentWindow || iframe.contentDocument;
if (doc.document) {
  doc = doc.document;
}

I've also see this approach:

var iframe = document.getElementById('my_iframe');

iframe = (iframe.contentWindow) ? iframe.contentWindow :
         (iframe.contentDocument.document) ? iframe.contentDocument.document :
         iframe.contentDocument;

iframe.document.open();
iframe.document.write('Hello World!');
iframe.document.close();

That confuses me, since it seems that if iframe.contentDocument.document is defined, you're going to end up trying to access iframe.contentDocument.document.document.

There's also this:

var frame_ref = document.getElementsByTagName('iframe')[0];

var iframe_doc = frame_ref.contentWindow ? frame_ref.contentWindow.document :
    frame_ref.contentDocument;

In the end, I guess I'm confused as to which properties hold which properties, whether contentDocument is equivalent to document or whether there is such a property as contentDocument.document, etc.

Can anyone point me to an accurate/timely reference on these properties, or give a quick briefing on how to efficiently access an <iframe>'s window and document properties in a cross-browser way (without the use of jQuery or other libraries)?

Thanks for any help!

+1  A: 

all of the modern browsers except Chrome support both iframereference.contentWindow and iframereference.contentDocument, but only if the page opened in the iframe is on the same domain as the page containing the iframe.

To include Chrome, use var iwin=iframereference.contentWindow, idoc=iwin.document

.contentDocument is the window.document of the page in the iframe, as is contentWindow.document, but not .contentDocument.document.

Chrome may include support for .contentDocument in some future version- I hope so, because it is also the way all the other browsers find the document contained in an Object element, type text/html, where the data attribute is the url of an html page.

kennebec
Thanks, kennebec! So, I did some testing keeping in mind your feedback. It actually looks like IE (at least IE 7) is the straggler on contentDocument; Chrome appeared to support it. Would `var win = iframe.contentWindow; var doc = iframe.contentDocument || iframe.contentWindow.document;` be a sufficient and stable cross-browser (back to IE 6) check for the `window` and `document` objects?
Bungle
A: 

There's an easier way that's been around longer... use window.frames to get a reference to the frame's window object.

By name or id:

var iframe_doc = window.frames.my_iframe.document;

or if you prefer:

var iframe_doc = window.frames['my_iframe'].document;

or by index:

var iframe_doc = window.frames[0].document;

Good reference for window.frames here: http://developer.mozilla.org/en/DOM/window.frames

An excerpt:

each item in the window.frames pseudo-array represents the window object corresponding to the given <frame>'s or <iframe>'s content, not the (i)frame DOM element (i.e. window.frames[ 0 ] is the same thing as document.getElementsByTagName( "iframe" )[ 0 ].contentWindow)

no