Javascript all images loaded

imagesLoaded

.imagesLoaded() returns a jQuery Deferred object. This allows you to use .always() , .done() , .fail() and .progress() .

$('#container').imagesLoaded() .always( function( instance )  console.log('all images loaded'); >) .done( function( instance )  console.log('all images successfully loaded'); >) .fail( function()  console.log('all images loaded, at least one is broken'); >) .progress( function( instance, image )  var result = image.isLoaded ? 'loaded' : 'broken'; console.log( 'image is ' + result + ' for ' + image.img.src ); >);

Vanilla JavaScript

You can use imagesLoaded with vanilla JS.

imagesLoaded( elem, callback ) // options imagesLoaded( elem, options, callback ) // you can use `new` if you like new imagesLoaded( elem, callback )
  • elem Element, NodeList, Array, or Selector String
  • options Object
  • callback Function — function triggered after all images have been loaded

Using a callback function is the same as binding it to the always event (see below).

// element imagesLoaded( document.querySelector('#container'), function( instance )  console.log('all images are loaded'); >); // selector string imagesLoaded( '#container', function() . >); // multiple elements var posts = document.querySelectorAll('.post'); imagesLoaded( posts, function() . >);

Bind events with vanilla JS with .on(), .off(), and .once() methods.

var imgLoad = imagesLoaded( elem ); function onAlways( instance )  console.log('all images are loaded'); > // bind with .on() imgLoad.on( 'always', onAlways ); // unbind with .off() imgLoad.off( 'always', onAlways );

Background

Detect when background images have loaded, in addition to s.

Set < background: true >to detect when the element’s background image has loaded.

// jQuery $('#container').imagesLoaded(  background: true >, function()  console.log('#container background image loaded'); >); // vanilla JS imagesLoaded( '#container',  background: true >, function()  console.log('#container background image loaded'); >);

Set to a selector string like < background: '.item' >to detect when the background images of child elements have loaded.

// jQuery $('#container').imagesLoaded(  background: '.item' >, function()  console.log('all .item background images loaded'); >); // vanilla JS imagesLoaded( '#container',  background: '.item' >, function()  console.log('all .item background images loaded'); >);

Events

always

// jQuery $('#container').imagesLoaded().always( function( instance )  console.log('ALWAYS - all images have been loaded'); >); // vanilla JS imgLoad.on( 'always', function( instance )  console.log('ALWAYS - all images have been loaded'); >);

Triggered after all images have been either loaded or confirmed broken.

done

// jQuery $('#container').imagesLoaded().done( function( instance )  console.log('DONE - all images have been successfully loaded'); >); // vanilla JS imgLoad.on( 'done', function( instance )  console.log('DONE - all images have been successfully loaded'); >);

Triggered after all images have successfully loaded without any broken images.

fail

$('#container').imagesLoaded().fail( function( instance )  console.log('FAIL - all images loaded, at least one is broken'); >); // vanilla JS imgLoad.on( 'fail', function( instance )  console.log('FAIL - all images loaded, at least one is broken'); >);

Triggered after all images have been loaded with at least one broken image.

progress

imgLoad.on( 'progress', function( instance, image )  var result = image.isLoaded ? 'loaded' : 'broken'; console.log( 'image is ' + result + ' for ' + image.img.src ); >);

Triggered after each image has been loaded.

  • instance imagesLoaded — the imagesLoaded instance
  • image LoadingImage — the LoadingImage instance of the loaded image

Properties

LoadingImage.img

LoadingImage.isLoaded

Boolean — true when the image has successfully loaded

imagesLoaded.images

Array of LoadingImage instances for each image detected

var imgLoad = imagesLoaded('#container'); imgLoad.on( 'always', function()  console.log( imgLoad.images.length + ' images loaded' ); // detect which image is broken for ( var i = 0, len = imgLoad.images.length; i  len; i++ )  var image = imgLoad.images[i]; var result = image.isLoaded ? 'loaded' : 'broken'; console.log( 'image is ' + result + ' for ' + image.img.src ); > >);

Webpack

Install imagesLoaded with npm.

You can then require(‘imagesloaded’) .

// main.js var imagesLoaded = require('imagesloaded'); imagesLoaded( '#container', function()  // images have loaded >);

Use .makeJQueryPlugin to make .imagesLoaded() jQuery plugin.

// main.js var imagesLoaded = require('imagesloaded'); var $ = require('jquery'); // provide jQuery argument imagesLoaded.makeJQueryPlugin( $ ); // now use .imagesLoaded() jQuery plugin $('#container').imagesLoaded( function() . >);

Browserify

npm install imagesloaded --save
var imagesLoaded = require('imagesloaded'); imagesLoaded( elem, function() . > );

Use .makeJQueryPlugin to make to use .imagesLoaded() jQuery plugin.

var $ = require('jquery'); var imagesLoaded = require('imagesloaded'); // provide jQuery argument imagesLoaded.makeJQueryPlugin( $ ); // now use .imagesLoaded() jQuery plugin $('#container').imagesLoaded( function() . >);

Browser support

Use imagesLoaded v4 for Internet Explorer and other older browser support.

Development

Development uses Node.js v16 with npm v8

MIT License

imagesLoaded is released under the MIT License. Have at it.

Источник

Check if all the images in the page are loaded

The goal: check if all images in the page are loaded. If yes, call to a function, if not, again to check if all images are loaded. My try:

let checkImages = new Promise(resolve => < resolve(areCompleted()); >); function areCompleted() < let images = document.querySelectorAll('img'); images = Array.from(images); for (let i = 0; i < images.length; i++) < if (!images[i].complete) < return false; >> return true; > 
checkImages.then(completed => < if (completed) < completedFunction(); >else < // Check again >>); 

If the response is true, call a function, if not. I don’t know how to do the same check again, but I want to do that checking until the response is true.

This seems like a bizarre use of promises. Normally you would resolve it only when all the images had loaded.

Do you just want an event to trigger when all the images are loaded, or do you need to use a promise?

@Archer I want to use a Promise because if I do the checking with a while loop I can block the script. I don’t know if there are another methods.

Images trigger an event when they complete loading. You don’t need to keep checking over and over. I’ll write you some code.

1 Answer 1

This function will check for already loaded images and attach an event listener to all the others so that it can tell when every image in a given container is loaded.

function onImagesLoaded(container, event) < var images = container.getElementsByTagName("img"); var loaded = images.length; for (var i = 0; i < images.length; i++) < if (images[i].complete) < loaded--; >else < images[i].addEventListener("load", function() < loaded--; if (loaded == 0) < event(); >>); > if (loaded == 0) < event(); >> > var container = document.getElementById("container"); onImagesLoaded(container, function() < alert("All the images have loaded"); >);
 

This will still work if all the images have already loaded, due to being cached, or if there are no images in the container.

If you want to check all images in a page, simply change the container selector to the body instead.

var container = document.getElementsByTagName("body")[0]; 

Источник

Javascript — execute after all images have loaded

would answer my question. I have tried this but it executes the code the instant the page loads (not after the images load). If it makes any difference the images are coming from a CDN and are not relative. Anyone know a solution? (I’m not using jQuery)

10 Answers 10

Promise.all(Array.from(document.images).filter(img => !img.complete).map(img => new Promise(resolve => < img.onload = img.onerror = resolve; >))).then(() => < console.log('images finished loading'); >); 

Pretty backwards-compatible, works even in Firefox 52 and Chrome 49 (Windows XP era). Not in IE11, though.

Replace document.images with e.g. document.querySelectorAll(. ) if you want to narrow the image list.

It uses onload and onerror for brevity. This might conflict with other code on the page if these handlers of the img elements are also set elsewhere (unlikely, but anyway). If you’re not sure that your page doesn’t use them and want to be safe, replace the part img.onload = img.onerror = resolve; with a lengthier one: img.addEventListener(‘load’, resolve); img.addEventListener(‘error’, resolve); .

It also doesn’t test whether all images have loaded successfully (that there are no broken images). If you need this, here’s some more advanced code:

Promise.all(Array.from(document.images).map(img => < if (img.complete) return Promise.resolve(img.naturalHeight !== 0); return new Promise(resolve => < img.addEventListener('load', () =>resolve(true)); img.addEventListener('error', () => resolve(false)); >); >)).then(results => < if (results.every(res =>res)) console.log('all images loaded successfully'); else console.log('some images failed to load, all finished loading'); >); 

It waits until all images are either loaded or failed to load.

If you want to fail early, with the first broken image:

Promise.all(Array.from(document.images).map(img => < if (img.complete) if (img.naturalHeight !== 0) return Promise.resolve(); else return Promise.reject(img); return new Promise((resolve, reject) => < img.addEventListener('load', resolve); img.addEventListener('error', () =>reject(img)); >); >)).then(() => < console.log('all images loaded successfully'); >, badImg => < console.log('some image failed to load, others may still be loading'); console.log('first broken image:', badImg); >); 

Two latest code blocks use naturalHeight to detect broken images among the already loaded ones. This method generally works, but has some drawbacks: it is said to not work when the image URL is set via CSS content property and when the image is an SVG that doesn’t have its dimensions specified. If this is the case, you’ll have to refactor your code so that you set up the event handlers before the images begin to load. This can be done by specifying onload and onerror right in the HTML or by creating the img elements in the JavaScript. Another way would be to set src as data-src in the HTML and perform img.src = img.dataset.src after attaching the handlers.

Источник

Checking for multiple images loaded

I’m using the canvas feature of html5. I’ve got some images to draw on the canvas and I need to check that they have all loaded before I can use them. I have declared them inside an array, I need a way of checking if they have all loaded at the same time but I am not sure how to do this. Here is my code:

var color = new Array(); color[0] = new Image(); color[0].src = "green.png"; color[1] = new Image(); color[1].src = "blue.png"; 
color[0].onload = function() < //code here >color[1].onload = function() < //code here >

If I had a lot more images, Which I will later in in development, This would be a really inefficient way of checking them all. How would I check them all at the same time?

7 Answers 7

If you want to call a function when all the images are loaded, You can try following, it worked for me

var imageCount = images.length; var imagesLoaded = 0; for(var i=0; i > > function allLoaded()

Can’t you simply use a loop and assign the same function to all onloads?

var myImages = ["green.png", "blue.png"]; (function() < var imageCount = myImages.length; var loadedCount = 0, errorCount = 0; var checkAllLoaded = function() < if (loadedCount + errorCount == imageCount ) < // do what you need to do. >>; var onload = function() < loadedCount++; checkAllLoaded(); >, onerror = function() < errorCount++; checkAllLoaded(); >; for (var i = 0; i < imageCount; i++) < var img = new Image(); img.onload = onload; img.onerror = onerror; img.src = myImages[i]; >>)(); 

Use the window.onload which fires when all images/frames and external resources are loaded:

So, you can safely put your image-related code in window.onload because by the time all images have already loaded.

This doesn’t seem to solve it. I’ve implemented the window.onload event handler around the function caller that starts off the whole script but it still runs too early.

A hackish way to do it is add the JS command in another file and place it in the footer. This way it loads last.

However, using jQuery(document).ready also works better than the native window.onload.

You are using Chrome aren’t you?

Yah, the window.onload running early is a chrome bug. You can use browser sniffing with a setTimeout to delay it for chrome specifically.

Because the answer to /his/ question was «you are using a chrome and are seeing a bug.» While adding an event listener to each image is one possible solution to a generic problem, it wasn’t the one that solved /his/ problem.

The solution with Promise would be:

const images = [new Image(), new Image()] for (const image of images) < image.src = 'https://picsum.photos/200' >function imageIsLoaded(image) < return new Promise(resolve => < image.onload = () =>resolve() image.onerror = () => resolve() >) > Promise.all(images.map(imageIsLoaded)).then(() => < alert('All images are loaded') >)

Just onload method in for loop does not solve this task, since onload method is executing asynchronously in the loop. So that larger images in the middle of a loop may be skipped in case if you have some sort of callback just for the last image in the loop.

You can use Async Await to chain the loop to track image loading synchronously.

function loadEachImage(value) < return new Promise((resolve) => < var thumb_img = new Image(); thumb_img.src = value; thumb_img.onload = function () < console.log(value); resolve(value); // Can be image width or height values here >>); > function loadImages() < let i; let promises = []; $('.article-thumb img').each(function(i) < promises.push(loadEachImage( $(this).attr('src') )); >); Promise.all(promises) .then((results) => < console.log("images loaded:", results); // As a `results` you can get values of all images and process it >) .catch((e) => < // Handle errors here >); > loadImages(); 

But the disadvantage of this method that it increases loading time since all images are loading synchronously.

Also you can use simple for loop and run callback after each iteration to update/process latest loaded image value. So that you do not have to wait when smaller images are loaded only after the largest.

var article_thumb_h = []; var article_thumb_min_h = 0; $('.article-thumb img').each(function(i) < var thumb_img = new Image(); thumb_img.src = $(this).attr('src'); thumb_img.onload = function () < article_thumb_h.push( this.height ); // Push height of image whatever is loaded article_thumb_min_h = Math.min.apply(null, article_thumb_h); // Get min height from array $('.article-thumb img').height( article_thumb_min_h ); // Update height for all images asynchronously >>); 

Or just use this approach to make a callback after all images are loaded.

It all depends on what you want to do. Hope it will help to somebody.

Источник

Читайте также:  METANIT.COM
Оцените статью