Dom Refresh on Long Running Function

DOM refresh on long running function

SOLVED IT!! No setTimeout()!!!

Tested in Chrome 27.0.1453, Firefox 21.0, Internet 9.0.8112

$("#btn").on("mousedown",function(){
$('#btn').html('working');}).on('mouseup', longFunc);

function longFunc(){
//Do your long running work here...
for (i = 1; i<1003332300; i++) {}
//And on finish....
$('#btn').html('done');
}

DEMO HERE!

DOM not updating during long function

This is how browsers work. (And Electron's display is effectively a browser.) There's a single thread which is responsible for both updating the UI and running the client-side JavaScript code. (In Electron it's the "rendering thread.") So while your JavaScript code is running, the UI won't update.

There are two solutions:

  1. Have another thread do the heavy lifting and post updates periodically to the main thread. In a browser you'd do that with a web worker. Apparently you can have web workers with Electron as well, see this example. Or perhaps you could have the work done by your main process rather than your rendering process.

  2. Break up the logic so that you yield back to the browser periodically so it has a chance to update its display.

#1 is probably your better bet for the kind of number crunching you're doing. Here's an example counting from 1 to 1,000,000,000 with updates every 10,000:

// Get the contents of our worker script as a blobvar workerScript = document.getElementById("worker").textContent;var blob = new Blob(    [workerScript],    {        type: "text/javascript"    });
// Create an object URL for itvar url = (window.webkitURL || window.URL).createObjectURL(blob);
// Start the workervar worker = new Worker(url);worker.addEventListener("message", function(e) { if (e && e.data && e.data.type === "update") { display.textContent = "Value: " + e.data.value; }});
<script id="worker" type="javascript/worker">// The type on this script element means the browser// won't run it directly. It's here so we can turn it// into a blob to run the worker later.for (var n = 1; n <= 1000000000; ++n) {    if (n % 10000 === 0) {      self.postMessage({type: "update", value: n});    }}</script><div id="display">Waiting for worker to start...</div>

Long running jQuery method - how to refresh dom?

You can do what you want using setTimeout. It's like the same logic we use for doing animations.

// Code goes here
function load(index) {
var m = jQuery('#test').clone();
m.html("Element" + index)
jQuery('#test2').append(m);

if(index < 100) {
setTimeout(function() {
load(index + 1);
},100);
}
}

$(document).ready(function(){
load(0);
});

here is a plunker

Forcing a DOM refresh in Internet explorer after javascript dom manipulation

Can your longRunningOperation be called asynchronously?

Updating DOM during Javascript function execution

Since scripts run in a single thread in your browser, any method like yours will need to complete before the DOM is updated. What you can do, however, is use an iterative function with a small delay that allows the browser to redraw.

Here's an example...

window.myFunction = function(i) {    // calling a function here - passing i as a parameter, if needed    document.getElementById('mySpan').innerHTML = "Completed step " + i + "/500";    i++;    if (i <= 500) setTimeout(function() { myFunction(i) }, 1);}
myFunction(0);
<span id="mySpan"></span>

Refresh page and run function after - JavaScript

You need to call myFunction() when the page is loaded.

window.onload = myFunction;

If you only want to run it when the page is reloaded, not when it's loaded for the first time, you could use sessionStorage to pass this information.

window.onload = function() {
var reloading = sessionStorage.getItem("reloading");
if (reloading) {
sessionStorage.removeItem("reloading");
myFunction();
}
}

function reloadP() {
sessionStorage.setItem("reloading", "true");
document.location.reload();
}

DEMO

AngularJS: force DOM update during long-running loop (i.e. progress indicator)

It doesn't matter if you take the loop outside of the digest as long as it's part of the main thread and remains synchronous it won't update the DOM until it finishes.

Your options are:

  1. Set the each element analysis to be performed in a timeout function and update your progress from there. This is good if you don't care in what order the operations are finished, something like

    for(i=0; i<arr.length; i++){
    $timeout(function(){
    //do something here and increase the progress counter
    })
    }
  2. If you care about the order, use recursive functions something like

    function recursive(arr, index){
    if(arr.length==index-1){
    //you are done
    }
    //do something
    $timeout(function(){
    recursive(arr,index+1)
    })
    }
  3. If you don't care about old browsers, use webworker. This is a more complex solution; you can see it at w3schools.

Why does jQuery wait to update the DOM during function execution?

For an explanation, I found this answer as well as other solutions for similar problems.

A potential solution:

$(document).ready(function () {
$('h1').on('mousedown', function() {
$("h1").text("Change Complete");
})
$("h1").on('mouseup', function () {
SlowUpdate();
});
});

function SlowUpdate() {
// Take a bunch of time doing stuff
var i = 0;
while(i < 100000) {
console.log(i);
i++;
}
}


Related Topics



Leave a reply



Submit