In on-line ad delivery we utilize the <iframe> tag quite a lot. There are good reasons for serving ads in iframes. There are restrictions in communication between an iframe and its parent window when the two documents are served from different domains. This helps protect users as well as site publishers from malicious activity.

Iframes also provide advantages in the speed of delivery of an overall page. The parsing and display of an iframe’s content happens asynchronously to the rest of the parent window’s resources. This means that when an iframe is encountered during an initial page load it does not prevent the rest of the page from loading while the content of the iframe is loaded.

At AppNexus we’ve been developing some improved ad delivery mechanisms which leverage the advantages of iframes, in particular we’ve been leveraging the dynamic creation of iframes to serve ad content after some user interaction is applied. However, this has been a bit of an adventure as idiosyncrasies in how browsers handle the population of content in iframes and the rendering of their documents.

Let me illustrate.

Here’s how we would use JavaScript to create a new iframe, give it some properties, set its initial source, and add it to the existing document.

I’ve set the src attribute to ‘about:blank’. This is generally a good practice because IE can behave strangely when an iframe is appended to the document without a source. Setting the src to about:blank makes this a “friendly” iframe which means that javascript code running inside the iframe can interact with the DOM and javascript defined in its parent window and vice versa. In other words, there are no restrictions on the communication and code execution between the iframe window and the parent window.

There are several different ways we can add content to our new iframe:

Change the src attribute to an external document URL

Use the DOM’s open(), write(), close() API to inject content

Use the javascript: URI scheme.

Here are examples of each approach.

I can set the src attribute to an external file:

newIframe.src = 'myIframeContent.html';

If this was my intent all along, then there’s no need to start with the ‘about:blank’ src. I can set this as the src directly.

This is not convenient if we don’t have access to the site’s initial domain, and we want to maintain the “friendly” nature of the iframe. In such a case we can use the DOM API to open the iframe’s document and dynamically write content into it.

In external.js there is a variable defined which is referenced by the code which is being added in our document.write call. external.js is loaded asynchronous to the parsing of document.write(content), therefore at the time that we invoke this:

document.getElementById("innerCtnr").innerHTML = externalVar;

externalVar has not yet been defined and causes a ReferenceError.

To workaround this problem in IE we can make use of the javascript: URI scheme which makes bookmarklets and scriplets possible in all browsers. Instead of using document.open/write/close we use the following approach:

First, we assign the dynamic content to a variable on the iframe’s window object. Then we invoke it via the javascript: scheme. This not only renders the HTML properly, but loads and executes the scripts in the desired order.

Dynamic iframes are resourceful ways to add new content into a web page, but care and attention has to be paid as to how those iframes are injected with content to avoid errors caused by browser differences in loading and executing scripts added to those iframes.