Detect when an iframe starts to load new URL

66,447

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);
}
Share:
66,447
Philipp
Author by

Philipp

Updated on February 17, 2020

Comments

  • Philipp
    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
    Breixo over 9 years
    Nice 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
    Philipp about 8 years
    Wow, very impressive solution :) I love it!
  • jbyrd
    jbyrd over 7 years
    In my opinion, this is overly complex, and misses the main point that the key event should be onbeforeunload, not onunload. The OP clearly states he wants to know when a frame starts loading a new url. See stackoverflow.com/a/30719095/422845
  • Tejasvi Hegde
    Tejasvi Hegde about 7 years
    Perfect! nice idea!
  • Yugandhar Pathi
    Yugandhar Pathi about 7 years
    will this work if URL I am loading(in iFrame) is from different domain?
  • Lionel
    Lionel about 6 years
    As @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
    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
    Alisson Reinaldo Silva about 5 years
    Btw 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
    bodo almost 5 years
    Note that this only works when the iframe contentWindow has the same origin as the script trying to set the event listener.