14.12 Inserting and Populating an iframe Element

NN 6, IE 5

14.12.1 Problem

You want to create an iframe element, insert it into the current document, and place content into the iframe.

14.12.2 Solution

This task requires a little more than just creating elements and appending them to the document. This is a case in which one of the elements you createan iframerequires a document tree context before you can stuff it with data. The following code takes place in the global space. If you bury it inside a function, predeclare the newIframe variable as a global.

First, we are going to append an iframe to the end of the body element, and then we will put a dynamically generated form into the iframe. Begin the expected way, by creating the iframe element in memory, and inserting the empty iframe into the document:

// create a frame element node
var newIframe = document.createElement("iframe");
// insert it into the document to give it context;
// set a tiny size, or display:none if you don't want to see it

Next, obtain a reference to the document context that is needed for creating elements that are to go inside the iframe. For IE, that context is the document object inside the iframe's window object; for others, the main document is the appropriate context:

// get the browser-appropriate document context for content creation
if (navigator.appName =  = "Microsoft Internet Explorer") {
    var doc = newIframe.contentWindow.document;
} else {
    doc = document; 

Now create the form and elements inside the form using the browser-specific document context. Unfortunately, IE tends to race ahead with its processing of script statements, sometimes causing statements to execute before the components under construction arrive on the scene. Therefore, it is necessary to put the brakes on processing with a setTimeout( ) method (set to zero delay), so that the final action can take place in a stable environment:

// create a form node within suitable document context
var newForm = doc.createElement("form")
// create an input element node in the same context
var newField = doc.createElement("input");
// insert the field into the form
// create and insert more form controls here
// insert the form into the iframe via delay
setTimeout("finishIframe( )", 0);

Finally, the form can be inserted into the body of the iframe's document:

// complete content insertion
function finishIframe( ) {

14.12.3 Discussion

If you code the HTML for the iframe and its content in a regular HTML page, the elements for the form simply exist between the start and end tags of the iframe. This leads you logically to imagine that creating and inserting a form into a new iframe would use the same kind of document tree insertion that you see in Recipe 14.9 and Recipe 14.10. The difference is that an iframe element is a type of window object, just as if it were a different frame in a frameset. Therefore, to work with the iframe's content in a script, you must be able to access the document that lives inside the iframe. When your scripting context is that of the main document and all you have is a reference to the iframe, the avenue to the iframe's document is via the iframe's contentWindowa reference to the window in the frame. That window doesn't exist in the object model until the new iframe is inserted into the document.

This roundabout way of reaching the content of an element is limited to those elements that contain window and document objects: frame elements and iframe elements. An object element also has a level of indirection, but no window is involved. Instead, an object element (in the W3C DOM, but not supported in IE as of Version 6) has a contentDocument property. You won't have to worry about this situation for any other HTML elements.

14.12.4 See Also

Recipe 14.3 for using an iframe to blend separate HTML documents together; Recipe 14.9 for creating a new element; Recipe 14.10 for creating element text content.