JavaScript library for creating & manipulating 'sourceless' iframe documents (i.e. those without an external document src); jQuery plugin.
JavaScript
Latest commit 0431ced Sep 12, 2012 @premasagar Change demo display URL

README.textile

AppleOfMyIframe is a jQuery Plugin. It provides a simple JavaScript API for creating iframe elements, and injecting HTML into them. It allows manipulation of the iframe’s contents in a similar way to jQuery’s interactions with more common DOM elements.

Quick demo

Clone the repository and run demo/index.html.
Read the wiki for the full API.

Overview

iframes are commonly used to embed external documents into a web page (by adding the resource’s URL to the iframe element’s src attribute). However, iframe can also be created from scratch by JavaScript, and have their HTML contents injected into them, without the need to load in any external resources. This allows an entirely scriptable document to be embedded within the host page, which is useful to self-contain and shield the iframe’s contents from the CSS and JavaScript contained within the host document. This is handy when creating widgets and other kinds of modules.

See the Sqwidget project, which provides AppleOfMyIframe as an optional plugin, to automatically insert widget contents into an iframe document, on-the-fly.

For an alternative approach to CSS sandboxing, see the CleanSlate project, which is based on a reset stylesheet composed entirely of !important rules.

The Problem

The standard browser API for working with iframes is convoluted and fragile, and the behaviour of iframes can vary wildly between browsers. This is a shame, because with a more modular web, there is an increasing need to control the sandboxing of content in the browser. Until now, it has been difficult to take advantage of this potential.

Browsers are fairly reliable when loading external resources into iframes, but exhibit quirky behaviour when injecting contents directly into the elements. For example:

  • When an iframe element is created and populated with content, if the iframe element is moved to a different part of the DOM (e.g. if it is drag-and-dropped like an iGoogle widget, or manipulated into a new position in the page), then the iframe’s contents is completely destroyed. This is seen in Firefox, Chrome, Safari and Opera – but not Internet Explorer.
  • When an iframe element is created, by default, it will have no doctype, and so it defaults to Quirks Mode in Internet Explorer.
  • The load event of the iframe is inconsistently triggered in different browsers. E.g. it may be fired when the element is created and added to the DOM, or when new HTML is written to the document, or when an existing iframe is moved to another part of the DOM.
  • IE6 doesn’t render iframes with an external document, if they are added to the DOM while they are hidden, and sometimes when the iframes are moved in the DOM
  • Opera doesn’t support the adoptNode method when applied to elements from a different iframe document
  • And so on…

AppleOfMyIframe smooths over all these cross-browser differences. It provides a clean and simple API for manipulating iframe documents, bringing the experience closer to that of using jQuery’s intuitive, chainable methods for manipulating basic DOM elements.

jQuery methods

The plugin creates two core methods:

jQuery.iframe()

This is used to create a new iframe element, wrapped inside a standard jQuery collection – i.e. $('<iframe></iframe>') – that has been extended with some additional methods.

jQuery(elem).intoIframe()

This is used to replace elements in the host document with an iframe, and inject those replaced elements into the iframe’s body.

Example usage

All arguments to $.iframe() are optional.

1. Create an iframe with some body contents, and add it to the document:

$.iframe('<p>hello world</p>') // Add contents to the iframe's body
        .appendTo('body'); // Use any jQuery method here

2. Insert HTML into the iframe’s head and body:

$.iframe(
    '<style>background-color:green;</style>',
    '<p>hello world</p>'
)
    .appendTo('body');

3. Load an external document, via its url:

$.iframe('http://example.com')
    .appendTo('body');

4. Supply various options:

$.iframe(
    '<p>hello world</p>',
    { // Options object - more options than shown here are available
        title:"Jimbob", // document title
        doctype:5, // HTML5 doctype
        autoheight:true, // Automatically resize iframe height, when content is added or removed from the iframe's body
        autowidth:false // As above, for the iframe width
    }
)
    .appendTo('body');

5. Supply a callback function, for when the iframe first loads:

$.iframe(
    '<p>hello world</p>', // This argument could be omitted, and instead added to the callback function
    function(){ // Callback function
        alert('iframe has loaded');
        this.body('<p>hello again</p>'); // Append contents to the body
    }
)
    .appendTo('body');

6. Inject elements that are already in the host document into an iframe:

$('<p>Hello world</p>') // A standard jQuery collection
    .appendTo('body')
    .intoIframe(); // Move the collection into the body of an iframe, and insert the iframe into the host document

See the project wiki for details on other methods and events.