jQuery .ready in a dynamically inserted iframe
Solution 1
I answered a similar question (see Javascript callback when IFRAME is finished loading?). You can obtain control over the iframe load event with the following code:
function callIframe(url, callback) {
$(document.body).append('<IFRAME id="myId" ...>');
$('iframe#myId').attr('src', url);
$('iframe#myId').load(function() {
callback(this);
});
}
In dealing with iframes I found good enough to use load event instead of document ready event.
Solution 2
Using jQuery 1.3.2 the following worked for me:
$('iframe').ready(function() {
$('body', $('iframe').contents()).html('Hello World!');
});
REVISION:! Actually the above code sometimes looks like it works in Firefox, never looks like it works in Opera.
Instead I implemented a polling solution for my purposes. Simplified down it looks like this:
$(function() {
function manipIframe() {
el = $('body', $('iframe').contents());
if (el.length != 1) {
setTimeout(manipIframe, 100);
return;
}
el.html('Hello World!');
}
manipIframe();
});
This doesn't require code in the called iframe pages. All code resides and executes from the parent frame/window.
Solution 3
In IFrames I usually solve this problem by putting a small script to the very end of the block:
<body>
The content of your IFrame
<script type="text/javascript">
//<![CDATA[
fireOnReadyEvent();
parent.IFrameLoaded();
//]]>
</script>
</body>
This work most of the time for me. Sometimes the simplest and most naive solution is the most appropriate.
Solution 4
Following DrJokepu's and David Murdoch idea I implemented a more complete version. It requires jQuery on both the parent and iframe and the iframe to be in your control.
iframe code:
var iframe = window.frameElement;
if (iframe){
iframe.contentDocument = document;//normalization: some browsers don't set the contentDocument, only the contentWindow
var parent = window.parent;
$(parent.document).ready(function(){//wait for parent to make sure it has jQuery ready
var parent$ = parent.jQuery;
parent$(iframe).trigger("iframeloading");
$(function(){
parent$(iframe).trigger("iframeready");
});
$(window).load(function(){//kind of unnecessary, but here for completion
parent$(iframe).trigger("iframeloaded");
});
$(window).unload(function(e){//not possible to prevent default
parent$(iframe).trigger("iframeunloaded");
});
$(window).on("beforeunload",function(){
parent$(iframe).trigger("iframebeforeunload");
});
});
}
parent test code:
$(function(){
$("iframe").on("iframeloading iframeready iframeloaded iframebeforeunload iframeunloaded", function(e){
console.log(e.type);
});
});
Solution 5
Found the solution to the problem.
When you click on a thickbox link that open a iframe, it insert an iframe with an id of TB_iframeContent.
Instead of relying on the $(document).ready
event in the iframe code, I just have to bind to the load event of the iframe in the parent document:
$('#TB_iframeContent', top.document).load(ApplyGalleria);
This code is in the iframe but binds to an event of a control in the parent document. It works in FireFox and IE.
Related videos on Youtube
EtienneT
I am the cofounder of LavaBlast Software. LavaBlast We build software for franchisors: easy to use point of sale software, a franchise management portal, interactive kiosks and e-commerce websites. FranchiseBlast ties these elements together by transferring data to and from a centralized management portal. Moreover, because we understand that collaboration is the key to growing a franchise offering, we’ve added software tools such as a wiki, forum, and blog into our integrated solution. We host and maintain the centralize portal, we take care of in-store software deployment & upgrades, and we handle off-site backups. This leaves you, the franchisor, the hard part: growing your franchise concept.
Updated on May 23, 2020Comments
-
EtienneT almost 4 years
We are using jQuery thickbox to dynamically display an iframe when someone clicks on a picture. In this iframe, we are using galleria a javascript library to display multiple pictures.
The problem seems to be that
$(document).ready
in the iframe seems to be fired too soon and the iframe content isn't even loaded yet, so galleria code is not applied properly on the DOM elements.$(document).ready
seems to use the iframe parent ready state to decide if the iframe is ready.If we extract the function called by document ready in a separate function and call it after a timeout of 100 ms. It works, but we can't take the chance in production with a slow computer.
$(document).ready(function() { setTimeout(ApplyGalleria, 100); });
My question: which jQuery event should we bind to to be able to execute our code when the dynamic iframe is ready and not just it's a parent?
-
Jason Kealey over 15 yearsAnd you confirm that galleria works when you load it directly instead of through an iframe, correct?
-
EtienneT over 15 yearsYes, galleria works perfectly when we use it directly in a normal page.
-
Robert MacLean almost 11 yearspossible duplicate of Javascript callback when IFRAME is finished loading?
-
-
NONA over 14 yearsWhat's is the movePreview fucntion referred to in setTimeout()?
-
Sky Sanders about 14 yearsFound the solution? Looks like Pier had already posted it. Whether you found it on your own or not, etiquette would be to accept his answer, thus rewarding the time he spent answering you.
-
Shay Erlichmen over 13 yearsShouldn't you set the load event prior to calling the attr('src')?
-
David Murdoch over 13 years+1 This solution works great for me! One great addition is that you can reach up to the
parent
to grab a copy of jQuery and useparent.$(document).ready(function(){ parent.IFrameLoaded( ); });
to initialize the iframe. -
Már Örlygsson about 13 years@cam8001: It was a typo - has now been fixed.
-
Barum Rho almost 13 yearsNo, it does not matter. Load event will not fire until the next event loop at minimum.
-
Mike Starov over 12 yearsthe load event will not work for iframes that are used for download. like <iframe src="my.pdf"/>
-
Pier Luigi over 12 years"Dynamically inserted" because the iframe tag is inserted in the DOM by javascript on the client. So the iframe can exixts or not on the page, based on condition or event that happens on the client.
-
Sukhpreet Singh Alang over 12 yearsProblem with load is that it fires when all images and subframes have loaded. A jQuery like ready event would be more useful.
-
Sukhpreet Singh Alang over 12 yearsProblem with load is that it fires when all images and subframes have loaded. A jQuery like ready event would be more useful.
-
Woodgnome over 12 yearsThe load event will not fire for iFrames that have already loaded by the time the load handler is bound. As such it is not comparable to
jQuery(document).ready()
for iFrames. The only solution I can think of is copying how jQuery does it for the frame that jQuery has been loaded in. -
Skunkwaffle about 12 yearsThis wasn't working for some reason, so I tried replacing the first two lines with:
myFrame = $('<iframe src="' + src + '" id="myFrame"></iframe>').appendTo('body');
and everything worked fine. -
Alex almost 12 years@PierLuigi Could you please explain the
callback
variable? What should it be? I really don't understand -
Pier Luigi almost 12 years
callback
is any javascript function you want to be called once iframe has loaded. It can be a function local to the caller window or even a function defined in iframe window. You can access iframe window withwindow['myId']
on the caller. -
Zut over 11 yearsNote that there are two different .load()-functions. api.jquery.com/load for loading content into an object, and api.jquery.com/load-event to bind the onLoad event.
-
Julian almost 11 yearsI ended up using a polling solution too. Other solutions seemed to work only with partial success. However, for me, I needed to check for existence of a javascript function, rather than just for the contents of the iframe, before I had success. eg. (typeof iframe.contentWindow.myfunc == 'function')
-
w-- about 10 yearsfor whatever reason using $(iframe).ready(function...) in the parent would not work for me. It seemed like the callback function was getting executed before the iframe dom was ready. Using this method worked great!
-
NeoWang about 10 yearsWhat if I want to call a callback when the DOM of iframe is loaded? $.load is triggered only when everything(a lot of imgs) are loaded. What I need is the DOM ready event of the iframe. Can it be done without calling js across iframes?
-
Zain Shaikh about 10 yearsAny workaround available for catching the
load
event forpdf
files iniframe
? -
Pavel Savara over 9 yearsNote, that it doesn't work well on mobile browsers where the cache could be smaller than the size of PDF.
-
Teepeemm over 9 yearsThe difference between Pier's solution and this (and what I was missing in my code) is the context
top.document
that allows me to have code inside the iframe be able to tell when the iframe has loaded. (Althoughload
has been deprecated since this answer, and should be replaced withon("load")
.) -
eremzeit over 8 yearsThis solution is recursive which takes up memory for each call. If the iframe never loads, then it'll call deeper and deeper forever until memory runs out. I'd recommend
setInterval
for polling instead. -
Pang over 7 years
-
HASSAN MD TAREQ over 4 yearsWorked well for me