0

I would like to do something as simple as this:

Basically, I toggle the visibility of a loader element, then I simulate the processing of something by waiting 10 seconds and finally I toggle the visibility again. My problem is that I would like to force the redraw inside the testLoader callback function, but so far the update of the elements is only done after the callback has finished its execution. Is there a way of redrawing while the button callback is being executed?

testLoader : function() {
  var loader = document.getElementById("loader")
  var loaderVisibility = loader.style.visibility;

  if (loaderVisibility == "visible") {
    loader.style.visibility = "hidden"
  } else {
    loader.style.visibility = "visible"
  }

  var ms = 10000;
  var start = new Date().getTime();
  var end = start;
  while (end < start + ms) {
    end = new Date().getTime();
  }

  if (loaderVisibility == "visible") {
    loader.style.visibility = "hidden"
  } else {
    loader.style.visibility = "visible"
  }
}
<input type="button" id="testLoaderButton" value="Test Loader" onClick="testLoader()" />
mplungjan
  • 169,008
  • 28
  • 173
  • 236
Kuabel
  • 171
  • 1
  • 1
  • 9
  • Possible dupe. Please see this question: https://stackoverflow.com/questions/8840580/force-dom-redraw-refresh-on-chrome-mac – Martijn Vissers Oct 23 '18 at 11:56
  • Possible duplicate of [Force DOM redraw/refresh on Chrome/Mac](https://stackoverflow.com/questions/8840580/force-dom-redraw-refresh-on-chrome-mac) – Martijn Vissers Oct 23 '18 at 11:56
  • 1
    set a timer with a callback to run after the 10 seconds, instead of a single long-running function. – ADyson Oct 23 '18 at 11:59
  • 2
    `setTimeout` is the best approach here. – Rainbow Oct 23 '18 at 12:00
  • 3
    wow a synchronous `sleep`... – Kaiido Oct 23 '18 at 12:01
  • 1
    Your `while` loop halts the script execution. Seriously, have a look at [setTimeout](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout) – choz Oct 23 '18 at 12:01
  • Use some timer instead of a while loop so that there's a break in javascript execution between the start and 10 seconds later. As written, you're just spamming the javascript queue with the while loop, hence it never stops to redraw, since you're continuously calculating datetimes as fast as your computer allows. – Shilly Oct 23 '18 at 12:02
  • @Kaiido Yes, I used the synchronous sleep as a replacement for the actual code that I want to execute. – Kuabel Oct 24 '18 at 09:48
  • @choz Actually what I want is not to sleep, but to execute synchronous code. In the end I used setTimeout as a workaround for executing the actual code in a different thread and also without using Web Workers (I would have to refactor a lot of code for a simple change). – Kuabel Oct 24 '18 at 09:51

2 Answers2

1

Use setTimeout and don't block eventloop by using while

function testLoader() {
 var loader = document.getElementById("testLoaderButton");
 var loaderVisibility = loader.style.visibility;
 loader.style.visibility = "hidden";
 setTimeout(function () {
  loader.style.visibility = "visible";
 }, 1000);
}
<input type="button" id="testLoaderButton" value="Test Loader" onClick="testLoader()" />
ponury-kostek
  • 7,824
  • 4
  • 23
  • 31
0

In the end I came up with the following solution:

testLoader : function()
{
    var loader = document.getElementById("loader");
    loader.style.visibility = "visible";
    setTimeout(function () {
        do_processing()
        loader.style.visibility = "hidden";
    }, 500)
}

Basically I execute the code in another thread by using setTimeout and thus I dont block the javascript UI. PS: I know that Web Workers allow to simulate the creation of threads in javascript, but I preferred not to restructure my code into different files.

Kuabel
  • 171
  • 1
  • 1
  • 9