Determining when an iFrame is fully loaded

i’m dynamically creating an iframe on my page. the source for that iframe is a php page that prompts the user to download an excel file. sometimes it can take a little while for this file to be built by php.

i need a way to determine when the php page in the iframe is completely done.

currently, this is what i have…

<iframe onload="iframeLoaded();" src="report.php"></iframe>

the problem with onload is that it seems like it fires as soon as the page is even referrenced within the iframe…not completely finished.

any ideas?

Give the frame a name (e.g., myFrame) and try:

myFrame.document.body.onload = doSomething;

unfortunately that does the same thing as applying the onload in the html tag itself. it fires before the page is actually complete. :injured:

There must be something else at play here then. We’ll need to see your iframeLoaded function.

here’s the gist of what i got…

function downloadReport() {
   // create the iframe element with the name, id and src
   iframeReport.onload = loadedIframe; // this does fire, but not after the page is loaded
}

function loadedIframe() {
   // get rid of the iframe once the page has loaded
   document.body.removeChild(document.getElementById('iframeDownload'));
}

what it does is stall out the server because the report is being created by php, but then all of a sudden the iframe is killed before it’s actually loaded.

Load the script that generates the report into the top-level window instead of the IFRAME and see if it appears as expected.

the report appears as expected. it also works fine when i launch a tiny window with the php script and the download prompt appears. it works just fine in the iframe, as well, but i want to be able to determine when it’s done so i can clear the iframe.

Does report.php output html, or the raw binary excel file?

Sounds like it outputs html, in which case the onload is going to fire when the html is done loading. I’m guessing there is a seperate url which outputs the raw binary excel file, and the html generated by report.php directs the user to this other url.

it actually outputs an application/octet-stream.

here’s the header information:

header('Content-type: application/octet-stream');
header('Content-Disposition: attachment; filename=Report.xls;');
header('Content-Type: application/ms-excel');
header('Pragma: no-cache');
header('Expires: 0');

and the first part of the data:

<?xml version="1.0"?>
<?mso-application progid="Excel.Sheet"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" xmlns:html="http://www.w3.org/TR/REC-html40">
    <DocumentProperties xmlns="urn:schemas-microsoft-com:office:office">

do you know of a way to attach the onload event to the iframe in IE? i’ve had no luck. even hard coding it into the element isn’t working.

Oh right - IE DOM has a proprietary readyState property - I remember using it in place of onload. You could use a while loop and maybe a recursive function that queries the readyState property until its set to ‘complete’.

Edit: I used it to solve this guy’s question, try implementing it but without the scrollTo/parent part:

myiframe.onreadystatechange = function() {
   while (myiframe.readyState != 'complete') {
      alert(myiframe.readyState);
   }
   iframeIsLoaded();
}

Actually instead of the while, i think you just need…

myiframe.onreadystatechange = function() {
	    if ( myiframe.readyState == 'complete' ) {
		iframeIsLoaded();
	    }
	}

Assuming you still have not solved it.

the file is coming up, asking to be saved. which indicates that the report.php file is obviously done… but the readyState never is “complete”.

do you think since there is not DOM in report.php, this could be a part of the issue? that it’s just a php page outputting an excel file?

although, onload seems to work ok in FireFox so i dunno.

Ok. Could you paste your whole updated code?

myiframe.onreadystatechange = function() {
   if (myiframe.readyState == 'complete') {
      alert('good');
      iframeIsLoaded();
   }
}

full code? whole page?

here’s the javascript that’s called…

// button is clicked, disabling itself and creating the iframe
document.getElementById('downloadReport').disabled = 'disabled';

var downloadDiv = document.createElement("div");
downloadDiv.innerHTML = '<iframe id="myiframe" src="report.php"></iframe>';
document.body.appendChild(downloadDiv);

var myiframe = document.getElementById('myiframe');
if (firefox) {
    myiframe.onload = function () { iframeIsLoaded(); };
} else {
    myiframe.onreadystatechange = function() {
        if (myiframe.readyState == 'complete') {
            iframeIsLoaded();
        }
    }
}

function iframeIsLoaded() {
    // re-enable the button
    document.getElementById('downloadReport').disabled = '';
}
  1. Can you confirm that it’s feeding just IE by alerting inside of the else?
  2. Did you place an alert inside of iframeIsLoaded to check when it fires? Sometimes IE has issues with dom manipulation.
// button is clicked, disabling itself and creating the iframe
document.getElementById('downloadReport').disabled = 'disabled';
 
var downloadDiv = document.createElement("div");
downloadDiv.innerHTML = '<iframe id="myiframe" src="report.php"></iframe>';
document.body.appendChild(downloadDiv);
 
var myiframe = document.getElementById('myiframe');
if (firefox) {
    myiframe.onload = function () { iframeIsLoaded(); };
} else {
    alert('testing 1'); // this fires for IE
    myiframe.onreadystatechange = function() {
        alert('testing 2'); // this fires for IE
        if (myiframe.readyState == 'complete') {
            alert('testing 3'); // this never fires
            iframeIsLoaded();
        }
    }
}
 
function iframeIsLoaded() {
    // re-enable the button
    document.getElementById('downloadReport').disabled = '';
}