Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any way to wait for a Dom to be updated or asynchronously update the Dom?

I have a simple loading bar made with css, you update the css and the bar fills, super simple. I decided to update the bar with jQuery, works great but now I throw it into a practical environment. I have a bunch of files being downloaded and each time a file successfully downloads, it updates the position. The main problem is that it downloads the files so fast, and places the files correctly fast enough that it just doesn't update the loading bar unless I set a timeout interval of 300-400ms..it does log into console and I made an interval function that continously checks to see if a file is finished based on a global variable. No matter where I place the function to update the loading bar or how I update it, it seems the Dom will not react unless there's a big enough delay between files OR it will react at the very end (jumps to 100).

Is there any way to wait for a Dom to be updated by J's OR can you spot a problem in my code that causes this issue?

I also tried promises too but it didn't change how the browser reacts to the function.

This is all being done inside a Cordova environment but I tested it on chrome too and it works as long as the pc is powerful enough it seems.

The file Transfer function has an "on Success" too but that doesn't do anything as the Dom wont update in it until after all the downloads are done OR there's a delay

My solutions so far is to either intentionally lag the downloader, or lag it every 10 or 20 files to update the position

Edit: here's my loading bar Js

  var colorInc = 100 / 3;
  function setWater(myval)
  {
   var val = myval;
var waitForMe = $.Deferred();
  if(val != ""
  && !isNaN(val)
  && val <= 100
  && val >= 0)
{
  setTimeout(function(){waitForMe.resolve()}, 100);
  var valOrig = val;
  val = 100 - val;

  if(valOrig == 0)
  {
    //$("#percent-box").val(0);
    $(".progress .percent").text(0 + "%");
  }
  else $(".progress .percent").text(valOrig + "%");

  $(".progress").parent().removeClass();
  $(".progress .water").css("top", val + "%");

  if(valOrig < colorInc * 1)
    $(".progress").parent().addClass("red");
  else if(valOrig < colorInc * 2)
    $(".progress").parent().addClass("orange");
  else
    $(".progress").parent().addClass("green");
}
else
{
  setTimeout(function(){waitForMe.resolve()}, 100);
  $(".progress").parent().removeClass();
  $(".progress").parent().addClass("green");
  $(".progress .water").css("top", 100 - 67 + "%");
  $(".progress .percent").text(67 + "%");
  //$("#percent-box").val("");
}
return waitForMe.promise();
   };

Dowload tracker:

 var DLProgress = null;
 function updateProgress() {
  var oldNum = 0;
  DLProgress = setInterval(function(){
    if(!doneArts) {
       doneArts = true;
   downloadHelper("Articles",articleSize,33.33,0);
   }else if(currPos >= totalSize - 1){
   clearInterval(DLProgress);
   goNews();
    currPos = 0;
   doneArticles = false;
    doneJson = false;
   doneArts = false;
   } else if(currPos >= articleSize && !doneArticles) {
    doneArticles = true;
   downloadHelper("json",jsonSize,33.33,33.33);
    } else if(currPos >= articleSize + jsonSize && !doneJson) {
    doneJson = true;
     downloadHelper("img",imgSize,33.33,66.66);
     }
      if(oldNum != currPos) {
      oldNum = currPos;
      setWater(Math.ceil(100 * currPos / totalSize));
     }
     },5);
    }

Download Helper :

 function downloadHelper(name,size,maxPerc,startingPoint) {
 dataFiles[name].forEach(function(file){
   var getItem = localStorage.getItem(name+"/"+file[0]) || null; //might not work
   if(getItem === null || getItem !== file[1]) {
   //download file.
    if(file[0] !== null && file[1] !== null) {
      //setWater(Math.ceil(100 * currPos / totalSize)).done(function(){downloader(name+"/"+file[0],file[1]);});
      setTimeout(function(){downloader(name+"/"+file[0],file[1])},window.dltime);
      window.dltime += 200;
    }
   }
  });
 };

File transfer used : https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-file-transfer/

It Does update after each download helper has finished

Is there any way to wait for a Dom to be updated by J's OR can you spot a problem in my code that causes this issue?

like image 958
Ginzo Milani Avatar asked Aug 21 '18 01:08

Ginzo Milani


People also ask

Are DOM updates synchronous?

log() yields this result isn't surprising because a DOM update is a synchronous event. When the properties of the DOM object are modified, that change is thrown onto the call stack, and no proceeding event can execute until the stack is empty again.

How to wait until an element exists JavaScript?

To wait to do something until an element exists in the DOM, you can use JavaScript MutatationObserver API. As the name suggests, it can be used to listen out for changes in the DOM. You can then fire a (callback) function in response to this.

How is the DOM updated?

When the state of a component changes, React updates the virtual DOM tree. Once the virtual DOM has been updated, React then compares the current version of the virtual DOM with the previous version of the virtual DOM. This process is called “diffing”.


1 Answers

The DOM is updated each time the download is completed - it could be a problem.
We should separate upload progress and animation. When file is downloaded you should just change some kind of Model and use requestAnimationFrame recursively to animate a progress bar.

requestAnimationFrame is called 60 times per second, but will generally match the display refresh rate, paused in most browsers when running in background tabs or hidden <iframe>s in order to improve performance and battery life.

like image 136
Buggy Avatar answered Oct 06 '22 01:10

Buggy