jQuery Sharing between Parents and iFrames (inherit.js)

Share this article

Used to share between a single instance of jQuery through iFrames. Do note, the iFrame content must originate from the same domain, or this plugin will NOT work as expected. Download Page

/*!
 * jQuery iFrame Inheritance
 *
 * Copyright (c) 2009 Eric Garside (http://eric.garside.name)
 * Dual licensed under:
 *      MIT: http://www.opensource.org/licenses/mit-license.php
 *      GPLv3: http://www.opensource.org/licenses/gpl-3.0.html
 */
(function($){
	
	// Create a function in the Global Namespace so we can access
	// it from the iFrame by calling parent.inherit()
	this.inherit = function(child){
		// First, bind a copy of jQuery down into the DOM of the 
		// iFrame, so we can hook in functionality. Things may get
		// a bit confusing here, as we're creating this function in
		// the parent, but have to set it up internally to get called
		// as if it were in the child.
		child.jQueryInherit = this.parent.jQuery;
		
		// Bind a special ready callback binding function, to handle the
		// scope of responding to the document.ready hook instead of the 
		// parent's document.ready
		child.jQueryInherit.fn.ready = function( fn ) {
			// Attach the listeners
			child.jQueryInherit.hooks.bindReady();
			
			// If the DOM is already ready
			if (child.jQueryInherit.hooks.isReady)
				// Simply trigger the callback
				fn.call( child.document, child.jQueryInherit );
				
			// Otherwise, remember it so we can trigger it later
			else
				child.jQueryInherit.hooks.readyList.push( fn );
			
			return this;
		}
	
		// Create a namespace for hooking some functionality to the
		// iFrame, like document.ready decetion and handling
		child.jQueryInherit.hooks = {
			isReady: false,
			readyBound: false,
			readyList: [],
			// Mimic the readyBind() function in the child, so it can
			// set up the listeners for document.ready
			bindReady: function(){
				if (child.jQueryInherit.hooks.readyBound) return;
				child.jQueryInherit.hooks.readyBound = true;
			
				// 	Mozilla, Opera, and webkit nightlies support
				if ( child.document.addEventListener ) {
					child.document.addEventListener( "DOMContentLoaded", function(){
						child.document.removeEventListener( "DOMContentLoaded", arguments.callee, false );
						child.jQueryInherit.hooks.ready();
					}, false );
							
				// For IE
				} else if ( child.document.attachEvent ) {
					// ensure firing before onload,
					// maybe late but safe also for iframes
					child.document.attachEvent("onreadystatechange", function(){
						if ( child.document.readyState === "complete" ) {
							child.document.detachEvent( "onreadystatechange", arguments.callee );
							child.jQueryInherit.hooks.ready();
						}
					});
							
					// If IE and not an iframe
					// continually check to see if the document is ready
					if ( child.document.documentElement.doScroll && child == child.top ) (function(){
						if ( child.jQueryInherit.hooks.isReady ) return;
						
						try {
							// If IE is used, use the trick by Diego Perini
							// http://javascript.nwbox.com/IEContentLoaded/
							child.document.documentElement.doScroll("left");
						} catch( error ) {
							setTimeout( arguments.callee, 0 );
							return;
						}

						// and execute any waiting functions
						child.jQueryInherit.hooks.ready();
					})();
				}

				// A fallback to window.onload, that will always work
				jQuery.event.add( child, "load", child.jQueryInherit.hooks.ready );
			},
			// Hook the ready trigger to fire off the hook bindings
			ready: function(){
				// Make sure the DOM is not already loaded
				if ( !child.jQueryInherit.hooks.isReady ) {
					// Remember that the DOM is ready
					child.jQueryInherit.hooks.isReady = true;
				
					// If there are functions bound...
					if ( child.jQueryInherit.hooks.readyList ) {
						// Execute them all
						jQuery.each( child.jQueryInherit.hooks.readyList, function(){
							this.call( child.document, child.jQueryInherit );
						});
						
						// Reset the list of functions
						child.jQueryInherit.hooks.readyList = null;
					}
					
					// Trigger any bound ready events
					jQuery(child.document).triggerHandler('ready');
				}
			}
		};
		
		return child.jQuery = child.$ = function( selector, context ){
			// Test and see if we're handling a shortcut bind
			// for the document.ready function. This occurs when
			// the selector is a function. Because firefox throws
			// xpconnect objects around in iFrames, the standard
			// jQuery.isFunction test returns false negatives.
			if (selector.constructor.toString().match(/Function/) != null)
				return child.jQueryInherit.fn.ready( selector );
						
			// Otherwise, just let the jQuery init function handle the rest. Be sure we pass in
			// proper context of the child document, or we'll never select anything useful.
			else
				return child.jQueryInherit.fn.init(selector||this.document, context||this.document);
		}
	}
	
})(jQuery);

/******* Inside the Child Element *******
 * Inside the head of the iFrame Content, you'll need to make a call
 * to the following inheritance function, to set up jQuery for the
 * iFrame. The call returns the iFrame's personal jQuery object, which
 * means it can be used to trigger the document.ready event, helpful
 * for condensing code.
 */
parent.inherit(window);

// Example of using the inheritance function as document.ready
parent.inherit(window)(function(){
    alert( jQuery('.someElementInTheiFrameDom').text() );
});
Source

Frequently Asked Questions (FAQs) about jQuery, iFrames, and Inheritance

Can an iFrame inherit JavaScript from its parent page?

No, an iFrame cannot directly inherit JavaScript from its parent page. This is because an iFrame is considered a separate document and has its own JavaScript environment. However, there are ways to share data and functions between the parent page and the iFrame using methods like postMessage or directly accessing the iFrame’s contentWindow.

How can I share data between an iFrame and its parent page?

You can use the postMessage method to send data from the parent page to the iFrame or vice versa. This method allows you to send data in a safe and controlled manner, even across different domains. You can also directly access the iFrame’s contentWindow, but this only works if the iFrame and the parent page are on the same domain.

Can an iFrame inherit CSS from its parent page?

No, an iFrame cannot inherit CSS from its parent page. Similar to JavaScript, an iFrame is considered a separate document and has its own CSS environment. However, you can apply CSS to an iFrame by linking to a CSS file within the iFrame’s HTML or by using JavaScript to dynamically apply styles.

What is the contentWindow property in an iFrame?

The contentWindow property is a reference to the window object of an iFrame. This property can be used to access the JavaScript environment of the iFrame, allowing you to call functions or access variables within the iFrame. However, this only works if the iFrame and the parent page are on the same domain due to same-origin policy restrictions.

What is the postMessage method and how does it work?

The postMessage method is a way to safely send data across different windows, even if they are on different domains. This method works by sending a message event with the data to the target window, which can then listen for this event and receive the data. This method is particularly useful for communication between an iFrame and its parent page.

What is the same-origin policy and how does it affect iFrames?

The same-origin policy is a security measure implemented in web browsers that restricts how a document or script can interact with content from another origin. This policy affects iFrames by preventing them from accessing the JavaScript environment or DOM of the parent page if they are on different domains. However, methods like postMessage can be used to bypass these restrictions in a controlled manner.

Can I use jQuery in an iFrame?

Yes, you can use jQuery in an iFrame. However, you need to include the jQuery library within the iFrame’s HTML, as it cannot inherit the jQuery library from the parent page. Once included, you can use jQuery as you normally would within the iFrame.

How can I access an iFrame’s content with jQuery?

You can access an iFrame’s content with jQuery by using the contents method. This method returns a jQuery object containing the iFrame’s document, which you can then use to manipulate the iFrame’s content. However, this only works if the iFrame and the parent page are on the same domain due to same-origin policy restrictions.

Can I use AJAX to load content into an iFrame?

Yes, you can use AJAX to load content into an iFrame. However, this requires some additional steps compared to loading content into a regular HTML element. You need to create a new document within the iFrame and then insert the AJAX content into this new document.

Can I use JavaScript to dynamically create an iFrame?

Yes, you can use JavaScript to dynamically create an iFrame. You can do this by creating a new iFrame element with document.createElement, setting its properties like src and id, and then appending it to the document. Once created, you can interact with the iFrame just like any other iFrame.

Sam DeeringSam Deering
View Author

Sam Deering has 15+ years of programming and website development experience. He was a website consultant at Console, ABC News, Flight Centre, Sapient Nitro, and the QLD Government and runs a tech blog with over 1 million views per month. Currently, Sam is the Founder of Crypto News, Australia.

iframe data sharinginherit.jsjQuery
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week
Loading form