skip to Main Content

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


  1. Image load is asynchronous.

    If you wish to show only loaded images, just add them an hidden class such as:

    .hidden{
      display: none;
    }
    

    So yes, just add that class to every images:

    for (let i = 0; i < res.length; i++) {
      // Create img element
      let img = document.createElement("img")
      img.src = res[i]
      img.classList.add("hidden")
      
      img.addEventListener("load", (event) => event.target.classList.remove("hidden"))
    
      // You certainly have some code to add the img to DOM.
      // ...
    }
    

    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 documentation

    Login or Signup to reply.
  2. The 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:

        function addImage(url) {
            let img = document.createElement("img");
            img.addEventListener('load', function () {
                img.src = url;
                // and add to DOM
            });
            img.addEventListener('error', function () {
                console.log('Image load error: ' + url)
            });
        }
    
        for (let i = 0; i < res.length; i++) {
            addImage(res[i]);
        }
    

    An alternative to this is to pass the full array to the addImage function, and to unshift an item, then call itself recursively on load' and on error`.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search