/ Published in: jQuery
URL: http://eric.garside.name/inherit
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.
Expand |
Embed | Plain Text
/*! * 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() ); });
Comments
Subscribe to comments
You need to login to post a comment.

Thanks, but how to inherit plugins?
Thanks this is a really useful method! In a page (not developed by me!) there are multiple iFrames loaded (25 per page!) and the jQuery library needs to be in each, needless to say this is more bandwidth than anyone would be willing to donate (minified JQ = 70KB x 25 = 1750KB per page!) so obviously I would rather just inherit the jQ lib on the parent. This part has worked, the alert shows the text of an element within the iFrame no problem.
However, I am trying to use a plugin in the iFrame, but it's not working. The markup is as follows
Have I missed something in the set up of this? The targeted "li" elements all live within the iFrame. The jQ lib and inheritance script are all on the parent page and the alert works fine, but it won't allow me to use my plugin! Can someone please help?!?
^ meh, it parsed out my script tags that show it loading the plugin .js. As psudo code it kinda looks like this;
html head script: jQ library (minified) script: inheritance script (as found above) /head body iFrame (my document) html head script: (load my plugin) parent.inherit(window) $(li).ellipsis /head /html /iFrame /body /html
would the above work?
^ meh, it parsed out my script tags that show it loading the plugin .js. As psudo code it kinda looks like this;
html head script: jQ library (minified) script: inheritance script (as found above) /head body iFrame (my document) html head script: (load my plugin) parent.inherit(window) $(li).ellipsis /head /html /iFrame /body /html
would the above work?