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

旧时模样 提交于 2019-11-27 08:36:14
Kevin B

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
}

You have a loop that runs for 5 seconds and freezes the web browser during that time. Since the web browser is frozen it can't do any rendering. You should be using setTimeout() instead of a loop, but I'm assuming that loop is just a replacement for a CPU intensive function that takes a while? You can use setTimeout to give the browser a chance to render before executing your function:

jQuery:

$(function() {
    $('button').click(function(){
        (function(cont){
            $('div').text('Processing JQ...');  
            start = new Date();
            end = addSecs(start,5);
            setTimeout(cont, 1);
        })(function(){
            do {start = new Date();} while (end-start > 0);
            $('div').text('Finished JQ');   
        })
    });
});

Vanilla JS:

document.getElementsByTagName('a')[0].onclick = function(){
    doRun(function(){
         do {start = new Date();} while (end-start > 0);
         document.getElementById('msg').innerHTML = 'Finished JS';   
    });
    return false;
};

function doRun(cont){
    document.getElementById('msg').innerHTML = 'Processing JS...';
    start = new Date();
    end = addSecs(start,5);
    setTimeout(cont, 1);
}

You should also remember to always declare all variables using the var keyword, and avoid exposing them to the global scope. Here is a JSFiddle:

http://jsfiddle.net/Paulpro/ypQ6m/

I had to wait for jQuery to manipulate the DOM and then grap the changes (load form fields multiple times into a form, then to submit it). The DOM grew and the insertion took longer and longer. I saved the changes using ajax to have to user to be able to continue where he left off.

This did NOT WORK as intended:

jQuery('.parentEl').prepend('<p>newContent</p>');
doSave(); // wrapping it into timeout was to short as well sometimes

Since jQuery functions like .prepend() do continue the chain only when done, the following seemed to do the trick:

jQuery('.parentEl').prepend('<p>newContent</p>').queue(function() {
  doSave();
});
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!