views:

63323

answers:

5

We are using jQuery thickbox to dynamically display an iFrame when someone click 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 100ms, 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 parent.

Thanks!

+42  A: 

I answered a similar question (see http://stackoverflow.com/questions/164085/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.

But if you want a 'iframe-document-ready' event, check the $.frameReady() plugin (http://ideamill.synaptrixgroup.com/?page_id=18) although it seems to be no more developed...

Pier Luigi
+2  A: 

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.

DrJokepu
this will not work on a cross-domain location
vsync
+3  A: 

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.

EtienneT
Found 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.
Sky Sanders
+3  A: 

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(movePreview, 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.

What's is the movePreview fucntion referred to in setTimeout()?
cam8001
A: 

Try this

<iframe id="testframe" src="about:blank" onload="if (testframe.location.href != 'about:blank') testframe_loaded()"></iframe>

All you need to do then is create the javascript function testframe_loaded()

Danny G