Home > Mobile >  How to display and hide loader before and after the image in printed on screen through API?
How to display and hide loader before and after the image in printed on screen through API?

Time:01-01

I want the user to enter a specific number and display that many images with the help of Unsplash API, but when the function calling the API is called there is a gap of 5 seconds before images finally appear on screen, and in that gap, I want to display a gif(loader) and hide it when images are finally visible on DOM, but I am not able to achieve this, can someone help

// gif in HTML

 <div id="output">
        <img src="./loading.gif" id="load">
    </div>

javascript ->

let imgNum = document.querySelector('#num')
let btn = document.querySelector("#btn")
let output = document.querySelector("#output")
let loadImg = document.querySelector("#load")   // gif image
let url = "https://source.unsplash.com/random"
loadImg.style.visibility = 'hidden';

function disLoad() {
    loadImg.style.visibility = 'visible';
}
function hideLoad() {
    loadImg.style.display = "hidden" 
}

function displayFunc() {
    disLoad()
    let img= ""
    for (let i = 0; i < Number(imgNum.value); i  ) {
       let newImg = `<img src=${url}>`
        img  = newImg
    }
    hideLoad()
   output.innerHTML = img
}
btn.addEventListener("click", displayFunc)

CodePudding user response:

This is because the UI and your JS run on the same thread, so you add and remove the loading gif (after your processing is complete!) without the UI showing it.

You would need to add the gif and then run your processing, as a separate function, within a setTimeout() with a timeout of 0.

Detailed answer here

CodePudding user response:

The following code snippet loads a specific number of images with a temporary loading image.

The loading image is removed when the images are completely loaded in both the DOM with the onload event listener and the browser window with the complete property.

Update: The provided code snippet is dependent on https://source.unsplash.com/random, so it may display errors from rate limiting or URL changes.

let imgNum = document.querySelector('#num')
let btn = document.querySelector("#btn")
let output = document.querySelector("#output")
let loadImg = document.querySelector("#load")   // gif image
let preloadImg = document.querySelector("#preload")
let url = "https://source.unsplash.com/random"
loadImg.style.visibility = 'hidden'

/* This defines the number of completely-loaded images in the browser window. */
let imgLoadNum = 0

function disLoad() {
  /* The loaded image count and previous images are deleted after each new load. */
  imgLoadNum = 0
  preloadImg.innerHTML = ""
  loadImg.style.visibility = 'visible'
  preloadImg.style.visibility = "hidden"
}

function hideLoad() {
  loadImg.style.visibility = "hidden"
  preloadImg.style.visibility = "visible"
}

/* This defines the event listener for each DOM-ready image to wait for the browser window to load the image with setInterval(). */
let imgLoadEvent = function(element) {
  let imgLoaded = setInterval(function() {
    if (element.complete) {
      clearInterval(imgLoaded)
      imgLoadNum  
    }
  }, 100)
}

function displayFunc() {
  disLoad()
  let i = 0
  /* This declares a newImg variable to avoid repeated declarations in a loop. */
  let newImg

  for (i = 0; i < Number(imgNum.value); i  ) {
    /* This creates a new image element. */
    newImg = document.createElement("img")
    /* This adds the element to the list of new images. */
    preloadImg.appendChild(newImg)
    /* This adds the image source with a query string to avoid duplicate image loading. */
    newImg.setAttribute("src", url   "?"   i)
    /* This adds an image width for testing purposes. */
    newImg.setAttribute("width", "20")
    /* This attaches a DOM load event listener to the new image element that proceeds to a browser image load event. */
    newImg.addEventListener("onload", imgLoadEvent(newImg))
  }

  /* This creates a listener by setting an interval that verifies if all images are loaded from the number of loaded images. */
  let asyncImgLoad = setInterval(function() {
    if (imgLoadNum == i) {
      /* The listener is stopped and the completely-loaded images are displayed. */
      clearInterval(asyncImgLoad)
      hideLoad()
    }
  }, 100)
}

btn.addEventListener("click", displayFunc)
<div id="output">
<img alt="loading" src="./loading.gif" id="load">
<div id="preload">
<!-- Images loaded here. -->
</div>
</div>
<input id="num" value="10">
<button id="btn">load</button>

  • Related