2

I'm loading a lot of images when the user visits one specific site of my web. I have a JSON file which has the image filename and other relevant info of the images, which is loaded to the user via an AJAX call.

The steps are the following:

  1. The user visits the page and loads the JSON with jQuery
  2. Iterate over the JSON object and get the name of each image
  3. Clone a HTML element with jQUery, set the image data of each cicle and append the image element to the page
  4. Arrange the loaded images in a grid layout, using a third-party library called Waterfall.js

The problem is, after loading the JSON and cloning the images into the page, I don't know how to detect when the images are finished downloaded. This step is crucial to the Waterfall library to create the grid layout correctly. I'm trying to use another simple library by the same author to detect when the images are loaded(imgStatus), but I haven't figured out yet how to detect the event.

My JS code is the following:

/* step 1 */
var mJson = $.getJSON( '/static/json/somedata.json', function( mData ) {
  /* 
    some code goes here 
  */
  for( var m = 0; m < mData.length; ++m ) {
    var mTemplate = $( '.item-template .item' ).clone();
    $( mTemplate )
     .data( 'item-link', 'https://www.example.com/posts/' + mData[ m ].fblink )
     .find( '.item-image' ).attr( 'src', '/static/images/' + mData[ m ].image );
    $( mTemplate ).appendTo( '.items-grid' );        
  }
});

mJson.complete( function() {
  console.log( 'done json' );
  /* this is where I try to use imgStatus to detect when the images are loaded */
  imgStatus.watch( '.item-image', function( imgs ) {
    if( imgs.isDone() ) {
      /* when the images are loaded, I call waterfall to create the grid layout */
      waterfall( '.items-grid' );
    }
  });
});

The HTML is:

<section class="item-template hidden">
    <!-- this is the item template -->
    <div class="item" data-item-link="#">
        <img class="img-responsive item-image" src="#" />
        <div class="clearfix"></div>
    </div>
    <!-- end of item template -->
</section>

<section class="row">
    <div class="col-sm-12 items-grid">
         <!-- this is where the cloned items are inserted and the grid layout will be implemented -->            
    </div>
</section>

I know it's not the most efficient code and I can't wait to replace everything with a new version, but this is what I have to work with right now. Can someone help me to find a way to detect when the images are finished downloading? It can be with or without imgStatus or using another library. Thanks.

1 Answers1

0

This stackoverflow thread answer lead me to:

In the complete handler:

mJson.complete( function() {
  console.log( 'done json' );

  $(document).trigger('done-json');
});


/* Then you can do something like: */

$(document).on('done-json', function() {
  /* this is where I try to use imgStatus to detect when the images are loaded */
  imgStatus.watch( '.item-image', function( imgs ) {
    if( imgs.isDone() ) {
      /* when the images are loaded, I call waterfall to create the grid layout */
      waterfall( '.items-grid' );
    }
  });
});

If the above doesn't work:

/* step 1 */
var mJson = $.getJSON( '/static/json/somedata.json', function( mData ) {
  /* 
    some code goes here 
  */
  for( var m = 0; m < mData.length; ++m ) {
    var mTemplate = $( '.item-template .item' ).clone();
    $( mTemplate )
     .data( 'item-link', 'https://www.example.com/posts/' + mData[ m ].fblink )
     .find( '.item-image' ).attr( 'src', '/static/images/' + mData[ m ].image );
    $( mTemplate ).appendTo( '.items-grid' );
  }
  setTimeout(function() {
      $(document).trigger('done-appending-template');
  }, 1);
});

mJson.complete( function() {
  console.log( 'done json' );
});

$(document).on('done-appending-template', function() {
  /* this is where I try to use imgStatus to detect when the images are loaded */
  imgStatus.watch( '.item-image', function( imgs ) {
    if( imgs.isDone() ) {
      /* when the images are loaded, I call waterfall to create the grid layout */
      waterfall( '.items-grid' );
    }
  });
});

I haven't tried this, but I think it should get you on the semi-right track (probably a better way, but if it works...) See if you need to use the setTimeout to 1ms trick or not.

Also, another library you could try: https://github.com/desandro/imagesloaded

Community
  • 1
  • 1
damo-s
  • 1,008
  • 7
  • 16