Detect when an iframe starts to load new URL
Solution 1
I found a better solution if iframe and the container page is same origin, don't have to put extra code into the inner page:
<iframe src="same-origin.com" onload="content_finished_loading(this)"></iframe>
<script>
var indicator = document.querySelector('.loading-indicator');
var content_start_loading = function() {
indicator.style.display = 'block';
};
var content_finished_loading = function(iframe) {
indicator.style.display = 'none';
// inject the start loading handler when content finished loading
iframe.contentWindow.onunload = content_start_loading;
};
</script>
Solution 2
I came up with following solution - which is only possible because we control the content of the iframe content and the host-window
Inside the iframe we add following script to the page footer (all pages use the same template, so this is a change to a single file)
<script>
window.onunload = function() {
// Notify top window of the unload event
window.top.postMessage('iframe_change', '*');
};
</script>
Inside the host-window we add this script to monitor the iframe state
function init_content_monitor() {
var content = jQuery('.iframe');
// The user did navigate away from the currently displayed iframe page. Show an animation
var content_start_loading = function() {
alert ('NOW: show the animation');
}
// the iframe is done loading a new page. Hide the animation again
var content_finished_loading = function() {
alert ('DONE: hide the animation');
}
// Listen to messages sent from the content iframe
var receiveMessage = function receiveMessage(e){
var url = window.location.href,
url_parts = url.split("/"),
allowed = url_parts[0] + "//" + url_parts[2];
// Only react to messages from same domain as current document
if (e.origin !== allowed) return;
// Handle the message
switch (e.data) {
case 'iframe_change': content_start_loading(); break;
}
};
window.addEventListener("message", receiveMessage, false);
// This will be triggered when the iframe is completely loaded
content.on('load', content_finished_loading);
}
Philipp
Updated on February 17, 2020Comments
-
Philipp about 4 years
How can I detect that an iframe on my page starts to load a new page?
Our situation is:
- When iFrame content starts to change we need to display a "loading" animation and hide the search-box.
- I know how to handle the "iframe has finished to load" event (to hide the animation) but not how to catch the initial "starting to change" event...
Note: I can attach jquery "click" hook to the links on the menu, which will work. However, inside the iframe content there are many cross-reference links, and the "change" event also applies for them! So we need to catch event when user clicks on a link inside the iframe or when the iframe src is changed via javascript - because we also want to show the loading-animation and hide the search-box.
-
Breixo over 9 yearsNice solution, it helpe me. I change the window.onunload statment for this: $(window).on('beforeunload ',function() { window.top.postMessage('iframe_change', '*'); }); It was much faster for me.
-
Philipp about 8 yearsWow, very impressive solution :) I love it!
-
jbyrd over 7 yearsIn my opinion, this is overly complex, and misses the main point that the key event should be
onbeforeunload
, notonunload
. The OP clearly states he wants to know when a frame starts loading a new url. See stackoverflow.com/a/30719095/422845 -
Tejasvi Hegde about 7 yearsPerfect! nice idea!
-
Yugandhar Pathi about 7 yearswill this work if URL I am loading(in iFrame) is from different domain?
-
Lionel about 6 yearsAs @jbyrd mentioned in a comment below, using
iframe.contentWindow.onbeforeunload
instead of.onunload
will trigger the callback earlier, in fact just when the new request is sent. -
Alisson Reinaldo Silva about 5 years@YugandharPathi yes. notice the second argument of the
postMessage
method is '*', which means the messa is posted to the top window context regardless of the domain it's hosting it. so The iframe can be hosted anywhere else. -
Alisson Reinaldo Silva about 5 yearsBtw very nice solution. This helped me a lot, I also needed to know when the iframe started loading new URL, and this worked perfectly for my specific scenario.
-
bodo almost 5 yearsNote that this only works when the iframe contentWindow has the same origin as the script trying to set the event listener.