Exactly when does an IFRAME onload event fire?

28,794

Solution 1

The latter: <body onload= fires only when all dependent elements (css/js/img) have been loaded as well.

If you want to run JavaScript code when the HTML has been loaded, do this at the end of your HTML:

<script>alert('HTML loaded.')</script></body></html>

Here is a relevant e-mail thread about the difference between load and ready (jQuery supports both).

Solution 2

The above answer (using onload event) is correct, however in certain cases this seems to misbehave. Especially when dynamically generating a print template for web-content.

I try to print certain contents of a page by creating a dynamic iframe and printing it. If it contains images i cant get it to fire when the images are loaded. It always fires too soon when the images are still loading resulting in a incomplete print:

function printElement(jqElement){
    if (!$("#printframe").length){
        $("body").append('<iframe id="printframe" name="printframe" style="height: 0px; width: 0px; position: absolute" />');
    }

    var printframe = $("#printframe")[0].contentWindow;
    printframe.document.open();
    printframe.document.write('<html><head></head><body onload="window.focus(); window.print()">');
    printframe.document.write(jqElement[0].innerHTML);
    printframe.document.write('</body></html>');
//  printframe.document.body.onload = function(){
//      printframe.focus();
//      printframe.print();
//  };
    printframe.document.close();
//  printframe.focus();
//  printframe.print();

//  printframe.document.body.onload = function()...
}

as you can see i tried out several methods to bind the onload handler... in any case it will fire too early. I know that because the browser print preview (google chrome) contains broken images. When I cancel the print and call that function again (images are now cached) the print preview is fine.

... fortunately i found a solution. not pretty but suitable. What it does that it scans the subtree for 'img' tags and checking the 'complete' state of those. if uncomplete it delays a recheck after 250ms.

function delayUntilImgComplete(element, func){
    var images = element.find('img');
    var complete = true;
    $.each(images, function(index, image){
        if (!image.complete) complete = false;
    });
    if (complete) func();
    else setTimeout(function(){
        delayUntilImgComplete(element, func);}
    , 250);
}    

function printElement(jqElement){
    delayUntilImgComplete(jqElement, function(){
        if (!$("#printframe").length){
            $("body").append('<iframe id="printframe" name="printframe" style="height: 0px; width: 0px; position: absolute" />');
        }

        var printframe = $("#printframe")[0].contentWindow;
        printframe.document.open();
        printframe.document.write(jqElement[0].innerHTML);
        printframe.document.close();
        printframe.focus();
        printframe.print();
    });
}
Share:
28,794
Robin Rodricks
Author by

Robin Rodricks

Updated on October 27, 2020

Comments

  • Robin Rodricks
    Robin Rodricks over 3 years

    Does the IFRAME's onload event fire when the HTML has fully downloaded, or only when all dependent elements load as well? (css/js/img)

  • Tyler
    Tyler over 13 years
    I'm assuming the same is true for the main document itself, not just for iframes?
  • Yuri Dogandjiev
    Yuri Dogandjiev over 5 years
    The question was when does the iframe.onload event fire; not when the body.onload one fires. How is this answer relevant?