How to check if iframe is loaded or it has a content?

JavascriptJqueryIframe

Javascript 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");
});

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionnewbie29View Question on Stackoverflow
Solution 1 - JavascriptBiranchiView Answer on Stackoverflow
Solution 2 - JavascriptpratikabuView Answer on Stackoverflow
Solution 3 - JavascriptTushar ShuklaView Answer on Stackoverflow
Solution 4 - JavascriptOraneView Answer on Stackoverflow
Solution 5 - JavascriptMax HeiberView Answer on Stackoverflow
Solution 6 - JavascriptRaza AhmedView Answer on Stackoverflow
Solution 7 - Javascriptskimberk1View Answer on Stackoverflow
Solution 8 - JavascriptobimodView Answer on Stackoverflow
Solution 9 - JavascriptJimmy AdaroView Answer on Stackoverflow
Solution 10 - JavascriptPratap SinghView Answer on Stackoverflow
Solution 11 - JavascriptNate SkateView Answer on Stackoverflow
Solution 12 - JavascriptDanielView Answer on Stackoverflow
Solution 13 - JavascriptDiego FortesView Answer on Stackoverflow