Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery/Javascript - How to wait for manipulated DOM to update before proceeding with function

What I'm trying to do is to update a simple div to say "Processing..." before executing a CPU-intensive script (it takes 3-12 seconds to run, no AJAX) then update the div to say "Finished!" when done.

What I'm seeing is the div never gets updated with "Processing...". If I set a breakpoint immediately after that command, then the div text does get updated, so I know the syntax is correct. Same behavior in IE9, FF6, Chrome13.

Even when bypassing jQuery and using basic raw Javascript, I see the same issue.

You'd think this would have an easy answer. However, since the jQuery .html() and .text() don't have a callback hook, that's not an option. It's also not animated, so there is no .queue to manipulate.

You can test this yourselves using the sample code I prepared below that shows both the jQuery and Javascript implementations with a 5 second high-CPU function. The code is easy to follow. When you click either the button or the link, you never see "Processing..."

<!DOCTYPE html> <html> <head> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js" ></script> <script type="text/javascript"> function addSecs(d, s) {return new Date(d.valueOf()+s*1000);} function doRun() {     document.getElementById('msg').innerHTML = 'Processing JS...';     start = new Date();     end = addSecs(start,5);     do {start = new Date();} while (end-start > 0);     document.getElementById('msg').innerHTML = 'Finished JS';    } $(function() {     $('button').click(function(){         $('div').text('Processing JQ...');           start = new Date();         end = addSecs(start,5);         do {start = new Date();} while (end-start > 0);         $('div').text('Finished JQ');        }); }); </script> </head> <body>     <div id="msg">Not Started</div>     <button>jQuery</button>     <a href="#" onclick="doRun()">javascript</a> </body> </html> 
like image 386
pcormier Avatar asked Sep 08 '11 01:09

pcormier


People also ask

Does jQuery make DOM manipulation faster?

jQuery is a wrapper that normalizes DOM manipulation in a way that works consistently in every major browser. It's fully reasonable for it to perform 25x slower than direct DOM manipulation.

Does jQuery manipulate the DOM?

Projects In JavaScript & JQueryjQuery provides a number of methods to manipulate DOM in efficient way. You do not need to write big and complex code to set or get the content of any HTML element.


1 Answers

set it to processing, then do a setTimeout to prevent the cpu intensive task from running until after the div has been updated.

<!DOCTYPE html> <html> <head> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js" ></script> <script> function addSecs(d, s) {return new Date(d.valueOf()+s*1000);} function doRun() {     document.getElementById('msg').innerHTML = 'Processing JS...';     setTimeout(function(){          start = new Date();          end = addSecs(start,5);          do {start = new Date();} while (end-start > 0);          document.getElementById('msg').innerHTML = 'Finished Processing';        },10); } $(function() {     $('button').click(doRun); });     </script>     </head> <body>     <div id="msg">Not Started</div>     <button>jQuery</button>     <a href="#" onclick="doRun()">javascript</a> </body> </html> 

you can modify the setTimeout delay as needed, it may need to be larger for slower machines/browsers.

Edit:

You could also use an alert or a confirm dialog to allow the page time to update.

document.getElementById('msg').innerHTML = 'Processing JS...'; if ( confirm( "This task may take several seconds. Do you wish to continue?" ) ) {      // run code here } 
like image 105
Kevin B Avatar answered Sep 24 '22 06:09

Kevin B