skip to Main Content

I am not normally one to write JS, but I need this for a little project for my work that displays 4 images on some tv’s that management can update. I created a little site that displays the images and need it to refresh the image with new slides every so often as they are updated. This all works fine, but if someone names the image incorrectly it will be a broken link. How can I add a check to see if the image exists and if it doesn’t return a default image.

//sleep function
async function sleep(seconds) {
    return new Promise((resolve) => setTimeout(resolve, seconds * 1000));
}

async function setImage() {
    //get divs by class name
    const imageDiv1 = document.querySelector('.image1');
    const imageDiv2 = document.querySelector('.image2');
    const imageDiv3 = document.querySelector('.image3');
    const imageDiv4 = document.querySelector('.image4');

    //define const images
    const image0 = new Image();
    const image1 = new Image();
    const image2 = new Image();
    const image3 = new Image();
    const image4 = new Image();

    //define paths
    const defaultImage = 'default.png';
    const safteyImage = "..\Safety\Safety_current.png";
    const qualityImage = "..\Quality\Quality_current.png";
    const omImage = "..\O&M\O&M_current.png";    
    const announcementsImage = "..\Announcements\Announcements_current.png";    

    //set images to paths
    image0.src = defaultImage;
    image1.src = safteyImage; 
    image2.src = qualityImage;
    image3.src = omImage;
    image4.src = announcementsImage;

    //add images to canvas
    imageDiv1.appendChild(image1);
    imageDiv2.appendChild(image2);
    imageDiv3.appendChild(image3);
    imageDiv4.appendChild(image4);
    
    //infinite loop of updating image.
    while(true){
        await sleep(5); //only 5 seconds right now for testing.
            image1.src = safteyImage + "?" + new Date().getTime();
            image2.src = qualityImage + "?" + new Date().getTime();
            image3.src = omImage + "?" + new Date().getTime();
            image4.src = announcementsImage + "?" + new Date().getTime();
            imageDiv1.replaceChild(image1, image1);
            imageDiv2.replaceChild(image2, image2);
            imageDiv3.replaceChild(image3, image3);
            imageDiv4.replaceChild(image4, image4);
    }
}

//call setImage on load
window.onload = (event) => {
    setImage();
}

I am looking for a way to switch it to a default image within the while loop so it is always checking if it exists or not.

document.getElementsByClassName('.image1').onerror = function() {
    document.getElementsByClassName('.image1').src = "default.png";
}

doesnt seem to work for me. I also found a function that checks the status code, but since this is looking into a local file I dont this this approach works, which it didnt.

//check if an image exists, (non working)
function imageExists(image_url){
    var request = new XMLHttpRequest();
    request.open("GET", image_url, true);
    request.send();
    request.onload = function() {
        imageStatus = request.status;
        if(request.status == 200) {
            console.log('it exists');
        }else{
            console.log('nope');
        }
    }
}

2

Answers


  1. You can listen for the "error" event on the document itself. This obviates the need to attach event listeners on each individual image.

    document.addEventListener('error', e => {
        e.target.src = 'default.png';
    }, true);
    
    Login or Signup to reply.
  2. Here is the best solution

    Use the img tag for the default image:

    const image0 = Image();
    image0.src = defaultImage;
    

    Then for every image use the object tag, inserting a copy of the default image inside (so that it gets loaded of the object resource fails to load):

    const image1 = document.createElement("object");
    image1.appendChild(image0.cloneNode());
    

    To set the source of the images use data attribute:

    image1.data = safteyImage;
    

    This way if the resource represented by the object tag can’t be loaded, the default image gets loaded instead.


    by LL

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