Firstly, I see this question asked a few times but no answers seem satisfactory. What I am looking for is to be able to call a script at anytime and determine whether or not an iframe has loaded - and to not limit the script to require being added to the iframe tag itself in an onload property.
Here's some background: I have been working on an unobtrusive script to try and determine whether or not local iframes in the dom have loaded, this is because one of our clients includes forms on their website in iframes and many of them open in lightboxes - which dynamically add the iframes into the dom at any time. I can attach to the open event of the lightbox, but its hit or miss as to whether I can "catch" the iframe before it has loaded.
Let me explain a little more.
In my testing I've determined that the onload event will only fire once - and only if it is bound before the iframe actually loads. For example: This page should only alert "added to iframe tag" and the listener that is attached afterward does not fire - to me that makes sense. (I'm using the iframe onload property for simple example).
https://jsfiddle.net/g1bkd3u1/2/
<script>
function loaded () {
alert ("added to iframe tag");
$("#test").load(function(){
alert("added after load finished");
});
};
</script>
<iframe onload="loaded()" id="test" src="https://en.wikipedia.org/wiki/HTML_element#Frames"></iframe>
My next approach was to check the document ready state of the iframe which seems to work in almost all of my testing except chrome which reports "complete" - I was expecting "Access Denied" for cross domain request. I'm ok with a cross domain error because I can disregard the iframe since I am only interested in local iframes - firefox reports "unintialized" which I'm ok with because I know I can then attach an onload event.
Please open in Chrome: https://jsfiddle.net/g1bkd3u1/
<iframe id="test" src="https://en.wikipedia.org/wiki/HTML_element#Frames"></iframe>
<script>
alert($("#test").contents()[0].readyState);
</script>
I've found that if I wait just 100ms - then the iframe seems to report as expected (a cross domain security exception - which is what I want - but I don't want to have to wait an arbitrary length).
https://jsfiddle.net/g1bkd3u1/4/
<iframe id="test" src="https://en.wikipedia.org/wiki/HTML_element#Frames"></iframe>
<script>
setTimeout(function () {
try {
alert($("#test").contents()[0].readyState);
} catch (ignore) {
alert("cross domain request");
}
}, 100);
</script>
My current workaround / solution is to add the onload event handler, then detach the iframe from the dom, then insert it back into the dom in the same place - now the onload event will trigger. Here's an example that waits 3 seconds (hoping thats enough time for the iframe to load) to show that detaching and re-attaching causes the iframe onload event to fire.
https://jsfiddle.net/g1bkd3u1/5/
<iframe id="test" src="https://en.wikipedia.org/wiki/HTML_element#Frames"></iframe>
<script>
setTimeout(function(){
var placeholder = $("<span>");
$("#test").load(function(){
alert("I know the frame has loaded now");
}).after(placeholder).detach().insertAfter(placeholder);
placeholder.detach();
}, 3000);
</script>
While this works it leaves me wondering if there are better more elegant techniques for checking iframe load (unobtrusively)?
Thank you for your time.