basically I’m trying to create an image "feed" like an Facebook-type site but where every post is an image (sort of like IG I suppose), where all the images load in with particular divs and other elements attached to them. I’ve got my JS to the point where it’s populating all the HTML and CSS correctly and everything looks good.
The only thing is the dataset we’re supposed to use has some particular pictures that don’t load, and for these specific elements, I don’t want the entire set of divs to be drawn up only to not display an actual picture – this looks bad. I could hardcode it to just ignore certain numbers, but in the interest of scalability I’d like to find a better solution.
I’m using a for-loop to create all the HTML elements, assign classes, ids, etc. However, when I try to make a boolean variable that I set using the complete attribute or the onerror – it doesn’t seem to work properly. I use a conditional to check the boolean and continue if the image doesn’t exist.
This is the relevant section of the code:
function testImage(img) {
img.addEventListener('load', function () { imageexist = true });
img.addEventListener('error', function () { imageexist = false });
}
for (let i = 0; i < res.length; i++) {
//check image load
let img = document.createElement("img");
img.src = res[i];
testImage(img);
// img.onerror = function () {
// imageexist = false;
// }
//
setTimeout(console.log(imageexist), 500);
if (imageexist === false) {
continue;
}
// console.log(img.complete);
// if (!img.complete) {
// continue;
// }
}
As you can see, I’ve tried setting a boolean variable (imageexist) via both a helper function and as the result of img.onerror, as well as testing img.complete directly. Unfortunately neither of these seem to work – they either skip every element if I default imageexist to false, or skip none if I default it to true. the res is just the array of image URLs.
edit: as per first comment, should have clarified probably that I only moved the definition of the boolean variable outside of the for loop in order to test the testImage function – moving it back inside the for loop and trying the img.onerror or img.complete methods still does not give the correct result.
2
Answers
Image load is asynchronous.
If you wish to show only loaded images, just add them an
hidden
class such as:So yes, just add that class to every images:
When they will be loaded, the event listener, attached to every of those, will remove the
hidden
class.By the way, the
continue
keyword in a loop is to skip the rest of the code and go right away to the next iteration. MDN documentationThe problem with your code is that you loop through your response array, test and immediately reference the
imagexist
variable that is actually set later once the image is loaded.You need to wait until the image is loaded:
An alternative to this is to pass the full array to the
addImage
function, and tounshift
an item, then call itself recursively onload' and on
error`.