How to check if iframe is loaded or it has a content?
JavascriptJqueryIframeJavascript Problem Overview
I have an iframe with id = "myIframe" and here my code to load it's content :
$('#myIframe').attr("src", "my_url");
The problem is sometimes it take too long for loading and sometimes it loaded very quickly. So I must to use "setTimeout" function :
setTimeout(function(){
if (//something shows iframe is loaded or has content)
{
//my code
}
else
{
$('#myIframe').attr("src",""); //stop loading content
}
},5000);
All I want to know is how to find out if an iFrame is loaded or it has content. Using iframe.contents().find()
will not work. I can't use iframe.load(function(){})
.
Javascript Solutions
Solution 1 - Javascript
Try this.
<script>
function checkIframeLoaded() {
// Get a handle to the iframe element
var iframe = document.getElementById('i_frame');
var iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
// Check if loading is complete
if ( iframeDoc.readyState == 'complete' ) {
//iframe.contentWindow.alert("Hello");
iframe.contentWindow.onload = function(){
alert("I am loaded");
};
// The loading is complete, call the function we want executed once the iframe is loaded
afterLoading();
return;
}
// If we are here, it is not loaded. Set things up so we check the status again in 100 milliseconds
window.setTimeout(checkIframeLoaded, 100);
}
function afterLoading(){
alert("I am here");
}
</script>
<body onload="checkIframeLoaded();">
Solution 2 - Javascript
kindly use:
$('#myIframe').on('load', function(){
//your code (will be called once iframe is done loading)
});
Updated my answer as the standards changed.
Solution 3 - Javascript
I had the same issue and added to this, i needed to check if iframe is loaded irrespective of cross-domain policy. I was developing a chrome extension which injects certain script on a webpage and displays some content from the parent page in an iframe. I tried following approach and this worked perfect for me.
P.S.: In my case, i do have control over content in iframe but not on the parent site. (Iframe is hosted on my own server)
First:
Create an iframe with a data-
attribute in it like (this part was in injected script in my case)
<iframe id="myiframe" src="http://anyurl.com" data-isloaded="0"></iframe>
Now in the iframe code, use :
var sourceURL = document.referrer;
window.parent.postMessage('1',sourceURL);
Now back to the injected script as per my case:
setTimeout(function(){
var myIframe = document.getElementById('myiframe');
var isLoaded = myIframe.prop('data-isloaded');
if(isLoaded != '1')
{
console.log('iframe failed to load');
} else {
console.log('iframe loaded');
}
},3000);
and,
window.addEventListener("message", receiveMessage, false);
function receiveMessage(event)
{
if(event.origin !== 'https://someWebsite.com') //check origin of message for security reasons
{
console.log('URL issues');
return;
}
else {
var myMsg = event.data;
if(myMsg == '1'){
//8-12-18 changed from 'data-isload' to 'data-isloaded
$("#myiframe").prop('data-isloaded', '1');
}
}
}
It may not exactly answer the question but it indeed is a possible case of this question which i solved by this method.
Solution 4 - Javascript
Easiest option:
<script type="text/javascript">
function frameload(){
alert("iframe loaded")
}
</script>
<iframe onload="frameload()" src=...>
Solution 5 - Javascript
You can use the iframe's load
event to respond when the iframe loads.
document.querySelector('iframe').onload = function(){
console.log('iframe loaded');
};
This won't tell you whether the correct content loaded: To check that, you can inspect the contentDocument
.
document.querySelector('iframe').onload = function(){
var iframeBody = this.contentDocument.body;
console.log('iframe loaded, body is: ', body);
};
> Checking the contentDocument
won't work if the iframe src
points to a different domain from where your code is running.
Solution 6 - Javascript
in my case it was a cross-origin frame and wasn't loading sometimes. the solution that worked for me is: if it's loaded successfully then if you try this code:
var iframe = document.getElementsByTagName('iframe')[0];
console.log(iframe.contentDocument);
it won't allow you to access contentDocument
and throw a cross-origin error
however if frame is not loaded successfully then contentDocument
will return a #document
object
Solution 7 - Javascript
I'm not sure if you can detect whether it's loaded or not, but you can fire an event once it's done loading:
$(function(){
$('#myIframe').ready(function(){
//your code (will be called once iframe is done loading)
});
});
EDIT: As pointed out by Jesse Hallett, this will always fire when the iframe
has loaded, even if it already has. So essentially, if the iframe
has already loaded, the callback will execute immediately.
Solution 8 - Javascript
When an iFrame loads, it initially contains the #document, so checking the load state might best work by checking what's there now..
if ($('iframe').contents().find('body').children().length > 0) {
// is loaded
} else {
// is not loaded
}
Solution 9 - Javascript
If you need to know when the iframe is ready to manipulate, use an interval. In this case I "ping" the content every 250 ms and if there's any content inside target iframe, stop the "ping" and do something.
var checkIframeLoadedInterval = setInterval( checkIframeLoaded, 250 );
function checkIframeLoaded() {
var iframe_content = $('iframe').contents();
if (iframe_content.length > 0) {
clearInterval(checkIframeLoadedInterval);
//Apply styles to the button
setTimeout(function () {
//Do something inside the iframe
iframe_content.find("body .whatever").css("background-color", "red");
}, 100); //100 ms of grace time
}
}
Solution 10 - Javascript
I got a trick working as follows: [have not tested cross-browser!]
Define iframe's onload event handler defined as
$('#myIframe').on('load', function() {
setTimeout(function() {
try {
console.log($('#myIframe')[0].contentWindow.document);
} catch (e) {
console.log(e);
if (e.message.indexOf('Blocked a frame with origin') > -1 || e.message.indexOf('from accessing a cross-origin frame.') > -1) {
alert('Same origin Iframe error found!!!');
//Do fallback handling if you want here
}
}
}, 1000);
});
Disclaimer: It works only for SAME ORIGIN IFRAME documents.
Solution 11 - Javascript
A really great method is use jQuery AJAX. The parent frame would look like this:
<iframe src="iframe_load.php" style="width: 100%; height: 100%;"></iframe>
The iframe_load.php file would load the jQuery library and a JavaScript that attempts to load the destination URL in an AJAX GET:
var the_url_to_load = "http://www.your-website.com" ;
$.ajax({
type: "GET",
url: the_url_to_load,
data: "",
success: function(data){
// if can load inside iframe, load the URL
location.href = the_url_to_load ;
},
statusCode: {
500: function() {
alert( 'site has errors' ) ;
}
},
error:function (xhr, ajaxOptions, thrownError){
// if x-frame-options, site is down or web server is down
alert( 'URL did not load due to x-frame-options' ) ;
} });
IMPORTANT The destination must have contain the "Access-Control-Allow-Origin" header. Example in PHP:
HEADER( "Access-Control-Allow-Origin: *" ) ;
Solution 12 - Javascript
If you're hosting the page and the iframe on the same domain you can listen for the iframe's Window.DOMContentLoaded
event. You have to wait for the original page to fire DOMContentLoaded
first, then attach a DOMContentLoaded
event listener on the iframe's Window
.
Given you have an iframe as follows,
<iframe id="iframe-id" name="iframe-name" src="..."></iframe>
the next snippet will allow you to hook into the iframe's DOMContentLoaded
event:
document.addEventListener('DOMContentLoaded', function () {
var iframeWindow = frames['iframe-name'];
// var iframeWindow = document.querySelector('#iframe-id').contentWindow
// var iframeWindow = document.getElementById('iframe-id').contentWindow
iframeWindow.addEventListener('DOMContentLoaded', function () {
console.log('iframe DOM is loaded!');
});
});
Solution 13 - Javascript
You can do it like this:
const $iframe = document.querySelector(`iframe`);
$iframe.addEventListener("load", function () {
console.log("loaded");
});