1

I am going to do my best here to distinctly explain what my issue is without the use of jsfiddle because $(window).on("load") does not fire within their IDE.

I have a html 'wrapper' which dynamically loads (ajax) html into div.content.

<body>
<div class="header"></div>
<div class="overlay"></div>


<div class="loader hidden" align="center">
    <img src="images/loading.gif" />
</div>

<!-- Container for the content -->
<div class="content">
    <!-- dynamic content appears here -->
</div>



<div class="footer"></div>
</body>

At the start of a new piece of content being loaded, I toggle the visibility between the loading gif and the content div.

$(".content").toggleClass("hidden", true);
$(".loader").toggleClass("hidden", false);

At the end of the loading /ajax process I have the following code:

$(".content").load("screens/"+this.currentScreen+"/"+this.currentScreen + ".html .screen", function( response, status, xhr ) 
{
    //other code 
    //
    //
    $(window).on("load", function() {
        $(".content").toggleClass("hidden", false);
        $(".loader").toggleClass("hidden", true);
     });
 });

I chose $(window).on("load") because I only want div.content to be visible again once all the images have finished loading, as opposed to $(document).ready().

For the first piece of content to be loaded, this works perfectly. However for the second piece of content, the $(window).on("load") event never fires.

I have a hunch that this event is not allowed to be invoked a second time, or maybe it is unbound after being called?

I tried triggering / invoking the method but to no avail.

if((window.onload) === null)
{
    $(window).on("load", function() {
        console.log("$(window).on('load') called");
        $(".content").toggleClass("hidden", false);
        $(".loader").toggleClass("hidden", true);
    });
}
else
{
    $(window).trigger("load");
}

Also, I assure everyone that it isn't the content being loaded, because if I replace $(window).on("load") with $(document).ready() it works fine. I just desperately want to wait for the new images to have loaded.

How can I achieve this?

Zze
  • 18,229
  • 13
  • 85
  • 118

1 Answers1

2

The window's load event only executes once. Even when you dynamically add content, it will not be triggered. This behaviour is indeed different from ready(), where jQuery will call the callback always, even if the document is ready when it meets this code for the first time.

When adding content dynamically there is no "one-liner" to get a callback run when all images of that content have been loaded. The code you would need to write, would have to capture the load event for every image you load, and see which one was last, also taking care of images that did not load (because of an invalid reference, or they were cached).

The ImagesLoaded Plug-in provides a method that does all that. You can use it like this:

$(function () {
    $(".content").load("screens/"+this.currentScreen+"/"+this.currentScreen + ".html .screen", function( response, status, xhr ) 
    {
        //other code 
        //
        //
        $(".content").imagesLoaded( function() {
            // images have loaded
            $(".content").toggleClass("hidden", false);
            $(".loader").toggleClass("hidden", true);
        });
    });
});

So I would suggest to just include that plug-in, like this:

<script src="https://npmcdn.com/imagesloaded@4.1/imagesloaded.pkgd.min.js">
</script>

and use the imagesLoaded() method, like above code.

trincot
  • 317,000
  • 35
  • 244
  • 286
  • Very interesting, I will check this out immediately. - Thanks for the answer. – Zze May 19 '16 at 05:36
  • I got temporarily swapped to a different task - will know in the next few hours. Cheers. – Zze May 23 '16 at 08:52
  • Works perfectly. I am going to update my answer to show the fix. Thank you. – Zze May 23 '16 at 12:12
  • You're welcome. Note that you don't really need to mention the fix in the question. Readers will scroll to the accepted answer anyway. – trincot May 23 '16 at 12:21
  • I don't normally update my question to reflect the answer, but in this case I thought it might be necessary due to still needing the `$(document).ready({});` function, as you can see in the update. – Zze May 23 '16 at 12:24
  • Of course, that is still needed (unless you put the code at the end of your document). But I have updated my answer also to include that. I would however suggest not to call `ready` inside another callback. Just put it at the outer level (I used the short-cut `$(function () { ... } );`). – trincot May 23 '16 at 12:31
  • As a reference for my last statement, see this [Q&A](http://stackoverflow.com/questions/20246299/does-ajax-loaded-content-get-a-document-ready). – trincot May 23 '16 at 12:37
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/112686/discussion-between-zze-and-trincot). – Zze May 23 '16 at 12:40