jQuery / Javascript-как дождаться обновления управляемого DOM перед продолжением работы с функцией
то, что я пытаюсь сделать, это обновить простой div, чтобы сказать "обработка..."перед выполнением сценария с интенсивным процессором (для запуска требуется 3-12 секунд, без AJAX) обновите div, чтобы сказать "готово!- когда закончишь.
то, что я вижу, это div никогда не обновляется с "обработкой"...". Если я устанавливаю точку останова сразу после этой команды, то текст div обновляется, поэтому я знаю, что синтаксис правильный. Такое же поведение в IE9, FF6, Chrome13.
даже при обходе jQuery и используя базовый необработанный Javascript, я вижу ту же проблему.
вы думаете, что это будет простой ответ. Однако с помощью jQuery .html() and .text () не имеет крючка обратного вызова, это не вариант. Он также не анимирован, поэтому его нет .очередь для манипулирования.
вы можете проверить это сами, используя пример кода, который я подготовил ниже, который показывает как реализации jQuery, так и Javascript с 5-секундной функцией высокого процессора. Код легко следовать. Когда вы нажмите кнопку или ссылку, вы никогда не увидите "обработка"..."
<!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>
2 ответов
установите его на обработку, а затем выполните setTimeout, чтобы предотвратить запуск интенсивной задачи cpu до тех пор, пока div не будет обновлен.
<!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>
вы можете изменить задержку setTimeout по мере необходимости, она может быть больше для более медленных машин/браузеров.
Edit:
вы также можете использовать предупреждение или диалоговое окно подтверждения, чтобы разрешить обновление страницы.
document.getElementById('msg').innerHTML = 'Processing JS...';
if ( confirm( "This task may take several seconds. Do you wish to continue?" ) ) {
// run code here
}
у вас есть цикл, который работает в течение 5 секунд и замораживает веб-браузер в течение этого времени. Поскольку веб-браузер заморожен, он не может выполнять рендеринг. Вы должны использовать setTimeout()
вместо цикла, но я предполагаю, что цикл - это просто замена интенсивной функции процессора, которая занимает некоторое время? Вы можете использовать setTimeout, чтобы дать браузеру возможность рендеринга перед выполнением вашей функции:
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);
}
вы должны также не забудьте всегда объявлять все переменные с помощью ключевого слова var и не подвергать их воздействию глобальной области. Вот JSFiddle: