Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

500
Views
How to show/hide animated GIF during the execution of a function?

I want to display an animated GIF (spinner icon) during the execution of a function and then hide the GIF when the function is completed.

However, the code that I'm implementing does not display the GIF apparently because the function is hogging the thread and not allowing the GIF to ever be shown.

Example: (https://jsfiddle.net/jzxu8cLt/)

HTML
<button onclick="go();">Go</button>
<span id="result"></span>
<hr>
<img style="display: none;" id="spinner" src="https://upload.wikimedia.org/wikipedia/commons/b/b1/Loading_icon.gif">
JS
function longLoop() {
  let count = 1000000000;
  let result = 0;
  for (let i = 1; i <= count; i++) {
    result = i;
  }
  return result;
}

function go() {
  let spinnerElement = document.getElementById('spinner');
  let resultElement = document.getElementById('result');
  spinnerElement.style.display = 'block';
  let result = longLoop();
  resultElement.innerHTML = result;
  spinnerElement.style.display = 'none';
}

The go() function above should do the work of showing the GIF prior to calling a long running function, then will hide the GIF when the long running function is completed.

However, the GIF never has a chance to be displayed in the browser and I can't figure out how to get the GIF to be displayed. Note: If I place a breakpoint at the line that calls the longLoop() function, the GIF is displayed correctly.

What do I need to do to allow the GIF to be displayed and animated during the longLoop() function?

about 4 years ago · Juan Pablo Isaza
3 answers
Answer question

0

Yep you're right, since JavaScript is single-threaded, the longLoop function is blocking the event loop and not giving the browser a chance to render the gif.

JsFiddle solution: https://jsfiddle.net/12yf4tgd/

I used setTimeout to make the longLoop function asynchronous and wrap that in a Promise so that the other assignments run after it completes.

function go() {
  let spinnerElement = document.getElementById('spinner');
  let resultElement = document.getElementById('result');
  spinnerElement.style.display = 'block';

  new Promise(resolve => setTimeout(() => {
    resolve(longLoop())
  }))
  .then((result) => {
    spinnerElement.style.display = 'none';
    resultElement.innerHTML = result;   
  })
}

Since it is being handled elsewhere by some Web Api and not on the main call stack, it won't be blocking.

If you don't want to use .then() because of all the nesting, the other option is to make go() and async function to take advantage of async/await syntax.

async function go() {
  let spinnerElement = document.getElementById('spinner');
  let resultElement = document.getElementById('result');
  spinnerElement.style.display = 'block';
  let result = await new Promise((resolve, reject) => {
    setTimeout(() => resolve(longLoop()))
  })
  spinnerElement.style.display = 'none';
  resultElement.innerHTML = result;
}

They both work the same way.

about 4 years ago · Juan Pablo Isaza Report

0

Run your long running and revert code in a setTimeout with timing param omitted or 0 which will execute "immediately", or more accurately, the next event cycle, which will prevent the blocking.

function longLoop() {
  let count = 1000000000;
  let result = 0;
  for (let i = 1; i <= count; i++) {
    result = i;
  }
  return result;
}

function go() {
  let spinnerElement = document.getElementById('spinner');
  let resultElement = document.getElementById('result');
  spinnerElement.style.display = 'block';
  setTimeout(() => {
    let result = longLoop();
    resultElement.innerHTML = result;
    spinnerElement.style.display = 'none';
  })
}
<button onclick="go();">Go</button>
<span id="result"></span>
<hr>
<img style="display: none;" id="spinner" src="https://upload.wikimedia.org/wikipedia/commons/b/b1/Loading_icon.gif">

about 4 years ago · Juan Pablo Isaza Report

0

I will recommend use async/await for you pourpuse will be more readable code here a solutions:

function longLoop(timeout) {
  return new Promise(resolve => setTimeout(resolve, timeout));
}

async function go() {
  let spinnerElement = document.getElementById('spinner');
  let resultElement = document.getElementById('result');
  spinnerElement.style.display = 'block';
  let result = await longLoop(4000);
  
  spinnerElement.style.display = 'none';
 
}
about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!