How do I know a a batch of images are loaded? - javascript

I have a Javascript Map kit, and it use Image object to load images. Every time I move/resize the map, it will load many images. But I want to know how I can fire a function when all images are loaded after I do a move/resize action.
Is there a way that I can create a listener like "allimages.onload=function(){}" ?
Or is there any workaround?

You would have to maintain a count of how many images were yet to load, and call the final function when the outstanding image count reached 0. eg.
function nofunction() {}
function loadImages(srcs, callback) {
var images= [];
var imagen= srcs.length;
for (var i= 0; i<srcs.length; i++) {
var image= new Image();
image.onload=image.onerror= function() {
imagen--;
if (imagen==0) {
this.onload=this.onerror= nofunction;
callback();
}
};
image.src= srcs[i];
images.push(image);
}
return images;
}
...
var images= loadImages(['/img/1.gif', '/img/2.gif'], function() {
alert('yay');
});
for (var i= 0; i<images.length; i++)
mapelement.appendChild(images[i]);

A while ago I have written a blog post about detecting the load of a single image. You can use the example to build your function that checks if all images are loaded. I hope it will help.

Related

Check if an error was thrown when loading an image during page startup

I am trying to write a JS script that will look through the page when it loads to see if any images had an error loading, and to change the src of that image to a default image. What I was trying to do was to loop through all the list of images returned from document.images, and to check every image to see if it finished loading using image[i].complete, and if it didn't, then change the src of that image to the default link. It did not work for me, and I can't think of the solution.
window.onload = function() {
var images = document.images;
for (var i = 0; i < images.length; i++) {
if (!image[i].complete) {
images[i].src = 'assets/default-avatar.jpg';
}
}
}
The solution is to use the error event on IMG tags:
<img src="..." onerror="this.src = 'default_image_url';">
Because complete returns true even if the image couldn't be loaded (at least in some browsers), you could use naturalWidth. If no image is loaded naturalWidth is 0.
window.onload = function() {
var images = document.images;
for (var i = 0; i < images.length; i++) {
if (image[i].naturalWidth === 0) {
images[i].src = 'assets/default-avatar.jpg';
}
}
}

How to know if an Image is given an illegal source?

I have created a list of Image object. Every Image's onload function is the same:
function tracker() {
++loadedImage;
if (loadedImage === total) ..
}
images[i].src = urls[i];
This function tries to see if all the images are loaded, if so, call another function. However, several sources are illegal (maybe not existing) so the onload function will never be called for those images. I want to increment loadedImage even if the object is given an illegal source. However can I know if an Image is given an illegal source?
Thank you.
Images also have an error event. You can hook it too and count failed loads from here.
If you plan to support IE8-, be aware that load events won't fire if the image happens to be already present in the browser's cache.
Depending on what you want to achieve (and when), window.onload might be an alternative. It fires, when the document and all resources are loaded
<img src="http://lorempixel.com/100/100"/>
<img src="http://lorempixel.com/a/b"/>
<img src="http://placehold.it/200x50"/>
window.onload = function(evt) {
console.log('window.onload');
}
var imgs = document.getElementsByTagName('img');
for (var i = 0; i < imgs.length; ++i) {
var img = imgs[i];
img.onload = function(evt) {
console.log('src=' + this.src + ', ready');
}
img.onerror = function(evt) {
console.log('src=' + this.src + ', error');
}
}
JSFiddle

Changing a picture by clicking on it with Javascript

This is my first ever question on here and I figure it must have a simple answer but it's frustrated me for a while, especially since I'm new to Javascript. So I have many images and would like to change to the next one by clicking on it on the webpage, starting with a certain image, obviously. Now I could do this with nested if else statements but if you have many images you get too many ones nested into each other and it can get too complex so I figured there must be a simpler way of doing it. Here's an example of the code I had:
function changeImage()
{
var image=document.getElementById("mainImage")
if (image.src.match("image1.jpg"))
{
image.src="image2.jpg";
}
else if (image.src.match("image2.jpg"))
{
image.src="image3.jpg";
}
else
{
if (image.src.match("image3.jpg"))
{
image.src="image4.jpg";
}
else
{
image.src="image1.jpg";
}
}
}
So you can see it's not the best way to do it. I tried to do it with a switch statement but I couldn't either (and would appreciate it if someone told me if it could be done with one and how). As a last try I tried this but for some reason it jumps from image1 to image4 at once:
function changeImage()
{
var images = ["image1.jpg", "image2.jpg", "image3.jpg", "image4.jpg"]
var myImage = document.getElementById("mainImage")
for (i=0; i < images.length; i++)
{
if (myImage.src.match(images[i]))
{
myImage.src = images[i+1]
}
}
}
So I could really appreciate some help. Thanks in advance.
Your last changeImage goes to #4 immediately because you're changing the image in the for loop which causes the check within the loop to keep being true and so it runs all the way to the last index, at which point the check finally fails. Instead, you'll want to maintain the current image index with a variable. Then, just change myImage.src to images[currentIndex + 1] on each click. Try something like below. You'll want to run showNextImage on page load and then run it once each time the image is clicked.
<script>
var currentImageIndex = 0;
//Cycle through images
showNextImage() {
var images = ["image1.jpg", "image2.jpg", "image3.jpg", "image4.jpg"]
var myImage = document.getElementById("mainImage")
myImage.src = images[currentImageIndex];
currentImageIndex++;
if(currentImageIndex >= images.length)
currentImageIndex = 0;
}
</script>

Preloading images in an array (and waiting until they have downloaded)

So I came across another problem.
When I started redoing the webpage I am working on , I came across an idea - Why not have the page preload the materials, and while it's doing just that, show a loading screen?
Well, I made a function for that, but the thing is, it starts doing what it's supposed to, until it comes to the open() part of the image preloading. It simply does not work. It is because I am giving it the arguments[i] part that is causing it to stop there? Is there a better way to do it?
function mainPageLoad() {
var loadScreen = document.getElementById('pageload');
loadScreen.innerHTML = "<p>Loading<span id='loadingWhat'>...</span></p><img src='images/loading.gif?v2'>";
var loadspan = document.getElementById('loadingWhat');
loadspan.innerHTML = " images";
preloadImages(["images/logo.jpg"])
//loadspan.innerHTML = " content";
//preloadContent([""]);
}
function preloadImages() {
var images = new Array();
var imagesToLoad = arguments.length;
document.writeln(imagesToLoad);
var imagesLoaded = 0;
document.writeln(imagesLoaded);
for (i = 0; i < arguments.length; i++) {
document.writeln("Loading images.");
images[i] = new XMLHttpRequest();
document.writeln("Made object");
images[i].open("GET", arguments[i], true);
document.writeln("Well, that worked.");
images[i].send(null);
document.writeln("Sent.");
images[i].onreadystatechange = function() {
document.writeln("Ready state change!");
if (images[i].readystate == 4 && images[i].status == 200){
imagesLoaded = imagesLoaded + 1;
window.alertln("We have loaded another image.");
window.alertln("Image" + String(imagesLoaded) + "out of" + String(imagesToLoad));
}
}
}
}
window.onload = init;
Here's a much, much simpler way to preload images and have it call a callback when the images are done loading in a related prior question/answer: Image preloader javascript that supports events.

Precache a varying number of images in jQuery and call back if all are loaded

I would like to do an animation with the images, but only when they are all loaded.
When I start the animation with images still loading, it looks bad.
The images are dynamically added to the dom by parsing a json requested by javascript on $(document).ready.
After the images are loaded I would like to get a callback.
my core code is like this:
$('.gallery-block').each(function () {
$.ajax({
url: $(this).data("url"),
dataType: 'json',
outerthis: this,
success: function (json) {
$(this.outerthis).data("json", json);
var i = json.length;
while (i--) {
var preload = new Image();
preload.src = json[i];
}
$(this.outerthis).data("loaded", "true");
}
});
});
As you can see I'm trying to preload the images, but I don't know how fickle they are this way. They are not attached to the dom or anything.
The other problem is that I wnat the line
$(this.outerthis).data("loaded", "true");
only to be executed when the images are really preloaded.
Should I iterate a variable on every image's callback?
And probably this.outerthis is a bad design pattern, but I'm new to javascript.
The images don't need to be connected to the DOM to be loaded. What you can do is hook up an onload event to each image (before you set the URL), which will acts as your callback. Just count up the number of responses to onload and you can figure out when they're all loaded.
Something like this (untested):
var i, image,
preload = [], loaded = 0,
images = ["a", "b"], count = images.length;
for(i = 0; i < count; i++) {
image = new Image();
image.onload = onImageLoaded;
image.src = images[i] + ".jpg";
preload[i] = image;
}
function onImageLoaded() {
loaded++;
if(loaded === count) {
alert("done");
}
}

Categories