64

Does anyone know if there is such a thing?

I have a iframe that's being inserted with $.ajax() and I want to do some stuff after the contents from the iframe are completely loaded:

....
 success: function(html){  // <-- html is the IFRAME (#theiframe)
          $(this).html(html);   // $(this) is the container element
          $(this).show();
          $('#theiframe').load(function(){
             alert('loaded!');
          } 
....

it works, but I see the IFRAME is loaded twice (the alert also shows twice).

Alex
  • 66,732
  • 177
  • 439
  • 641
  • Try setting the src of the iframe before appending it to the DOM. This should prevent the load event from firing twice. – Abe May 22 '15 at 20:37

7 Answers7

85

use iframe onload event

$('#theiframe').on("load", function() {
    alert(1);
});
Johann Echavarria
  • 9,695
  • 4
  • 26
  • 32
m-khonsari
  • 978
  • 6
  • 9
62

If possible, you'd be better off handling the load event within the iframe's document and calling out to a function in the containing document. This has the advantage of working in all browsers and only running once.

In the main document:

function iframeLoaded() {
    alert("Iframe loaded!");
}

In the iframe document:

window.onload = function() {
    parent.iframeLoaded();
}
Tim Down
  • 318,141
  • 75
  • 454
  • 536
  • hey this works! but how can I call a function that's inside the `jQuery(document).ready` function of the parent document? – Alex Apr 26 '11 at 10:09
  • @Alex: You'll need to make sure the function is global, which you can do either by declaring it as a variable in the global scope before assigning a value to the variable inside your `ready()` function, or by explictly assigning it as a property of `window` inside your `ready()` function. For example: `$(document).ready(function() { window.iframeLoaded = function() { alert("Load"); }; /* Other stuff here */ })`; – Tim Down Apr 26 '11 at 10:32
  • it seems my double loading problem is me wrapping the iframe between DIV tags. For some weird reason browsers reload the iframe if you do this... – Alex Apr 26 '11 at 10:40
  • @Alex: Certainly some browsers reload the iframe document if you hide and show the iframe, or move it around in the DOM. – Tim Down Apr 26 '11 at 10:44
  • i don't understand how its working :( but thanks after all it worked for me >> window.onload = function() { parent.iframeLoaded(); } function iframeLoaded() { } var postTempBody = "${postTempBody}"; /*fill body value*/ if(postTempBody != ''){ window.iframeLoaded = function() { var $iframe = jQuery('#tinyMceEditor_ifr'); alert($iframe.length); $iframe.ready(function() { $iframe.contents().find("body").append(postTempBody); }); }; } – Tariq Husain Feb 23 '16 at 08:48
8

Along the lines of Tim Down's answer but leveraging jQuery (mentioned by the OP) and loosely coupling the containing page and the iframe, you could do the following:

In the iframe:

<script>
    $(function() {
        var w = window;
        if (w.frameElement != null
                && w.frameElement.nodeName === "IFRAME"
                && w.parent.jQuery) {
            w.parent.jQuery(w.parent.document).trigger('iframeready');
        }
    });
</script>

In the containing page:

<script>
    function myHandler() {
        alert('iframe (almost) loaded');
    }
    $(document).on('iframeready', myHandler);
</script>

The iframe fires an event on the (potentially existing) parent window's document - please beware that the parent document needs a jQuery instance of itself for this to work. Then, in the parent window you attach a handler to react to that event.

This solution has the advantage of not breaking when the containing page does not contain the expected load handler. More generally speaking, it shouldn't be the concern of the iframe to know its surrounding environment.

Please note, that we're leveraging the DOM ready event to fire the event - which should be suitable for most use cases. If it's not, simply attach the event trigger line to the window's load event like so:

$(window).on('load', function() { ... });
Community
  • 1
  • 1
Oliver
  • 9,239
  • 9
  • 69
  • 100
3

Without code in iframe + animate:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script language="javascript" type="text/javascript">

function resizeIframe(obj) {

    jQuery(document).ready(function($) {

        $(obj).animate({height: obj.contentWindow.document.body.scrollHeight + 'px'}, 500)

    });

}    
</script>
<iframe width="100%" src="iframe.html" height="0" frameborder="0" scrolling="no" onload="resizeIframe(this)" >
3

That's the same behavior I've seen: iframe's load() will fire first on an empty iframe, then the second time when your page is loaded.

Edit: Hmm, interesting. You could increment a counter in your event handler, and a) ignore the first load event, or b) ignore any duplicate load event.

Piskvor left the building
  • 91,498
  • 46
  • 177
  • 222
  • if I add `alert($(this).attr('src'));` inside the load function I get the same value twice ... – Alex Apr 26 '11 at 09:52
2

If you want it to be more generic and independent, you can use cookie. Iframe content can set a cookie. With jquery.cookie and a timer (or in this case javascript timer), you can check if the cookie is set each second or so.

//token should be a unique random value which is also sent to ifame to get set
iframeLoadCheckTimer = window.setInterval(function () {
        cookieValue = $.cookie('iframeToken');  
        if (cookieValue == token)
        {
            window.clearInterval(iframeLoadCheckTimer );
            $.cookie('iframeToken', null, {
                expires: 1, 
                path: '/'
         });
        }
 }, 1000);
2

You may use the jquery's Contents method to get the content of the iframe.

Jeff
  • 13,943
  • 11
  • 55
  • 103
suhair
  • 10,895
  • 11
  • 52
  • 63