Javascript with image preloader that supports events

I am trying to find a script image preloader.

So far I have found several, none of them supports the event that is fired when the preload is completed.

Does anyone know of any script or jQuery plugin that will do this?

We hope this question is suitable for stackoverflow - if not, feel free to delete it in an instant.

+6
source share
4 answers

Here's a function that preloads images from an array and calls your callback when the last one finishes:

function preloadImages(srcs, imgs, callback) { var img; var remaining = srcs.length; for (var i = 0; i < srcs.length; i++) { img = new Image(); img.onload = function() { --remaining; if (remaining <= 0) { callback(); } }; img.src = srcs[i]; imgs.push(img); } } // then to call it, you would use this var imageSrcs = ["src1", "src2", "src3", "src4"]; var images = []; preloadImages(imageSrcs, images, myFunction); 

And since we are now using promises for asynchronous operations, here is the version above that uses promises and notifies the caller according to the ES6 standard:

 function preloadImages(srcs) { function loadImage(src) { return new Promise(function(resolve, reject) { var img = new Image(); img.onload = function() { resolve(img); }; img.onerror = img.onabort = function() { reject(src); }; img.src = src; }); } var promises = []; for (var i = 0; i < srcs.length; i++) { promises.push(loadImage(srcs[i])); } return Promise.all(promises); } preloadImages(["src1", "src2", "src3", "src4"]).then(function(imgs) { // all images are loaded now and in the array imgs }, function(errImg) { // at least one image failed to load }); 

And, here is the version using 2015 jQuery promises:

 function preloadImages(srcs) { function loadImage(src) { return new $.Deferred(function(def) { var img = new Image(); img.onload = function() { def.resolve(img); }; img.onerror = img.onabort = function() { def.reject(src); }; img.src = src; }).promise(); } var promises = []; for (var i = 0; i < srcs.length; i++) { promises.push(loadImage(srcs[i])); } return $.when.apply($, promises).then(function() { // return results as a simple array rather than as separate arguments return Array.prototype.slice.call(arguments); }); } preloadImages(["src1", "src2", "src3", "src4"]).then(function(imgs) { // all images are loaded now and in the array imgs }, function(errImg) { // at least one image failed to load }); 
+24
source

For a more robust solution, consider this PRELOADER function with multiple callbacks ( jsFiddle ).

Saving is simple:

In this example, I pass the callbacks and the image hash inside the Object literal PRELOADER_OBJECT , and then override the callbacks inside the PRELOADER :

 // preloder object stores image hash // and event handler callbacks var PRELOADER_OBJECT = { imgArray:"http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg http://torwars.com/wp-content/uploads/2012/02/chewbacca-w-han-solo-anh.jpg".split(" "), progressCallback : function( percent ) { $( '#preloader_progress' ).html( 'preload progress complete : ' + percent + '%' ); console.log( 'preload progress complete : ', percent ); }, completeCallback : function( scope ) { // hide preload indicator, do something when finished console.log( 'preload complete!' ); $( '#preloader_modal' ).delay( 1000 ).animate( { opacity : 0 }, function( ) { $( '.preload_class' ).each( function( index ) { $( this ).delay( index * 100 ).animate( { opacity : 0 } ); } ); } ); } /*Localize params and create PRELOADER object. Needs to loadImages( ); iterate through hash and call onPreloadProgress( ) and onPreloadComplete( ) each time until finished. If you're still within bounds of the image hash, call progressCallback( ) recursively. When finished, fire onCompleteCallback( )*/ var PRELOADER = function( object ) { // preloader modal overlay this.modal = undefined; // progress indicator container this.progressIndicator = undefined; // image preload progress this.progress = undefined; // progress callback this.progressCallback = undefined; // complete callback this.completeCallback = undefined; // hash to store key : value pairs for image paths this.imgArray = undefined; // store images in preloadArray this.preloadArray = []; // initialize and localize our data this.initialize = function( ) { // create preload indicator and overlay modal this.createPreloaderModal( ); // image hash this.imgArray = object.imgArray; // progress callback event handler this.progressCallback = object.progressCallback; // complete callback event this.completeCallback = object.completeCallback; // load images this.loadImages( ); }; this.progressCallback = function( ) {}; // function to override this.completeCallback = function( ) {}; // function to override // load images into DOM and fire callbacks this.loadImages = function( ) { var that = this; // iterate through hash and place images into DOM $.each( PRELOADER_OBJECT.imgArray, function( index, object ) { this.image = $( "<img/>", { "src" : object, "class": "preload_class" } ).appendTo( 'body' ); // mark progress and call progressCallback( ) event handler that.progress = Math.ceil( ( index / PRELOADER_OBJECT.imgArray.length ) * 100 ); that.progressCallback( this.progress ); that.preloadArray.push( this.image ); } ); // check for array bounds and call completeCallback( ) if ( PRELOADER_OBJECT.imgArray.length ) { this.progressCallback( 100 ); this.completeCallback( this ); } }; // create modal to display preload data this.createPreloaderModal = function( ) { this.modal = $( '<div/>', { 'id' : 'preloader_modal' } ).appendTo( 'body' ); this.progressIndicator = $( '<h1/>', { 'id' : 'preloader_progress' } ).appendTo( this.modal ); }; }; // trigger event chain when DOM loads $( document ).ready( function( ) { // instantiate PRELOADER instance and pass // our JSON data model as a parameter var preloader = new PRELOADER( PRELOADER_OBJECT ); // initialize preloader preloader.initialize( ); } ); 

};

With a heavy load on the site to require an image pre-loader, the modal text display could easily be modified to support data-driven jQuery animations.

+2
source

Preloading and loading are one and the same. You can insert an image (either create a new one or change the "src" attribute of an existing one), but hide the element with $("element").hide() or something like that. Before you do this, attach the load event handler as follows:

 var images = ["src1", "src2", "src3", "src4"]; var len = images.length; for(i=0; i<len; i++){ $("parent element").html('<img id="new-img" style="display:none;" src="'+images[i]+'"/>'); $("new-img").load(function(){ //Your image is now "preloaded" //Now you can show the image, or do other stuff $(this).show(); }); } 
0
source

Preloading requires additional work, such as creating new image elements, monitoring if they are all loaded, and then replacing them with existing ones in the DOM. However, you can do this directly on DOM <img> elements infinitely many times without replacing them.

We can use the Fetch API to access images until they are loaded within promise.all() , and then just replace the src attributes of the img elements at the right time using window.requestAnimationFrame()

In the following example, I update the src attributes of img elements 10 times. Depending on the delay, I use the time it takes to load 4 images from the API. Therefore, as soon as we upload all the images, I immediately place a new request, calling the same function refreshImagesNTimes recursively.

Of course, you can upload as many images as you want and display them in groups at exact time intervals using the simple setTimeout mechanism.

 function refreshImagesNTimes(nodeList,count = -1){ var imgPromises = Array.from({length: nodeList.length}) .map(_ => fetch("https://unsplash.it/480/640/?random").then(res => res.blob())); Promise.all(imgPromises) .then(function(blobs){ window.requestAnimationFrame(_ => nodeList.forEach((img, i) => img.src = (window.URL || window.webkitURL).createObjectURL(blobs[i]))); --count && refreshImagesNTimes(nodeList, count); }); } var images = document.querySelectorAll("#container img"); refreshImagesNTimes(images,10); 
 #container { display: flex; flex-wrap: wrap; justify-content: space-evenly; align-items: center; margin: auto; width: 75vw; height: 56.25vw; background-color: #000; box-sizing: border-box; } img { width: 45%; height: 45%; background-color: thistle; } 
 <div id="container"> <img> <img> <img> <img> </div> 
0
source

Source: https://habr.com/ru/post/902356/


All Articles