Supply more than one alternatives image source for img html tag?

Viewed 365

I have two alternative images and one image as default in case the first two images are not found.

<img 
    src='image1.png'
    onError="this.onerror=null;this.src='image2.png';"
    onError="this.onerror=null;this.src='default.png';" />

Then I tested on three <img /> I found image1.png and image2.png works correctly but in case there are not image1.png and image2.png, the default image default.png does not display.

Any tips on how can I use more than one alternative images like my case above?

3 Answers

You may want to use addEventListener instead, keeping track of your position in an array of possible images.

<img src='image1.png'/>
<script>
function addFallbackSources(img, sources){
  let idx = 0;
  img.addEventListener("error", e=>{
      if(idx >= sources.length) throw new Error("No images left to try");
      img.src = sources[idx++];
  });
}
addFallbackSources(document.querySelector('img'), ["image2.png", "default.png"]);
</script>

You could add a data-alt-src attribute that holds the values of the alternates, then have the onerror attribute call the loadAltImage function that simply loads the next alternate image index. This will essentially call itself recursively.

<img src="image1.png" data-alt-src="image2.png,default.png" onerror="loadAltImage(this)" />
function loadAltImage(element) {
  const alternatives = element.dataset.altSrc.split(',');
  const nextLoadIndex = parseInt(element.dataset.loadIndex || 0);
  
  if(nextLoadIndex < alternatives.length) {
    element.src = alternatives[nextLoadIndex].trim();
    element.dataset.loadIndex = nextLoadIndex + 1;
  }
}

Something Like follows may work.

function setNextAvailableImage(element, image_list) {
    const current_img = element.src
    let next_img = 'default.png'
    let found_index = -1
    for (let i = 0; i < image_list.length; i ++) {
        if (current_img.indexOf(image_list[i]) != -1) {
            found_index = i
            break
        }
    }

    if (found_index == -1 && image_list.length > 0) {
        element.src = image_list[0]
    }
    else if (found_index + 1 < image_list.length) {
        next_img = image_list[found_index + 1]
        element.src = next_img
    } else {
        element.src = next_img
    }
    
}
<img src='image1.png' onError="setNextAvailableImage(this, ['image2.png', 'image3.png'])"/>

Related