Search code examples
jqueryimageloadingpreloadimagesloaded

How to load a large amount of images through jQuery ImagesLoaded


I have a page that loads approx 150+ images into a page. The structure for the image is this:

HTML CODE

<table class="form-table">
  <input type="hidden" name="bgtype" id="bgtype" value="pattern"/>
  <tr class="wpbp-field-patternbg">
    <th style="width:20%"><label for="patternbg">Pattern</label></th>
    <td><div id="wpbp-pattern-select">
        <div class="description">Select a pattern you would like to be applied as the background. Click on a pattern to select it.<br>
        </div>
        <input class="radio" type="radio" name="patternbg" id="patternbg2" value="45degreee_fabric.png"  checked='checked'>
        <label for="patternbg2" class="is-loading"><a class="pattern_preview" data-img="45degreee_fabric.png" data-content="45degreee fabric"><img src="45degreee_fabric.png" alt="" class="wpbp-pattern-img "/></a></label>
        <input class="radio" type="radio" name="patternbg" id="patternbg3" value="patterns/60degree_gray.png" >
        <label for="patternbg3" class="is-loading"><a class="pattern_preview" data-img="60degree_gray.png" data-content="60degree gray"><img src="60degree_gray.png" alt="" class="wpbp-pattern-img "/></a></label>
        <input class="radio" type="radio" name="patternbg" id="patternbg4" value="always_grey.png" >
        <label for="patternbg4" class="is-loading"><a class="pattern_preview" data-img="always_grey.png" data-content="always grey"><img src="always_grey.png" alt="" class="wpbp-pattern-img "/></a></label>
        </div></td>
  </tr>
</table>

( I have removed the full path to the images to make the code above at a minimum )

CSS CODE

#wpbp-pattern-select.is-loading {
  background-image: url('../images/loading.gif');

}
#wpbp-pattern-select .is-loading img {
  opacity: 0;
}

JQUERY

var $container = $('#wpbp-pattern-select');
$imgs = $container.find('img'),

// use ImagesLoaded
$container.imagesLoaded()
  .progress( onProgress )
// reset progress counter
imageCount = $container.find('img').length;
console.log( imageCount + ' properly loaded images' );

// triggered after each item is loaded
function onProgress( imgLoad, image ) {
  var $item = $container.find('img');
  $item.removeClass('is-loading');
}

What I want to achieve is to have a preloading spinner (.is-loading) display on each individual image until that certain image has been loaded. When it is finished loading the spinner will remove displaying the original image.

I have tried playing around with the jQuery imagesLoaded library to get this to work but I can't get it right. Can this be done?

Any help would be greatly appreciated, thanks


Solution

  • Okay first in your CSS you define #wpbp-pattern-select .is-loading img but in your JS you try to remove the class from the image itself:

    function onProgress( imgLoad, image ) {
      var $item = $container.find('img');
      $item.removeClass('is-loading');
    }
    

    is this by design? however, try the following js:

    $(document).ready(function(){
      var $container = $('#wpbp-pattern-select');
        $imgs = $container.find('img');
    
      // all images are hidden by css
    
      $imgs.each(function() {
        var el = $(this),
            checkforloaded = setInterval(function() {
              var image = el.get(0);
              if (image.complete || image.readyState == 'complete' || image.readyState == 4) {
                clearInterval(checkforloaded);
                el.removeClass('is-loading'); // or: el.closest('label').removeClass('is-loading');
              }
            }, 20);
      });
    });
    

    Im just not sure how this will perform with many images, though