Что я пытаюсь сделать, - это обновить простой Div, чтобы сказать «Обработка ...», прежде чем выполнять интенсивный процессор CPU (требуется 3-12 секунд, чтобы запустить, нет AJAX), затем обновить Div, чтобы сказать «Закончено!» когда закончится.
Что я вижу, это Div никогда не обновляется с «обработкой ...». Если я установлю точку останова сразу после этой команды, то текст DIV обновляется, поэтому я знаю, что синтаксис правильный. Та же поведение в IE9, FF6, Chrome13.
Даже при обмке jQuery и используя базовый сырой JavaScript, я вижу ту же проблему.
Вы бы подумаете, что это будет легкий ответ. Тем не менее, поскольку jQuery .html () и .text () У вас нет обратного вызова, это не вариант. Также не анимировано, поэтому нет. Не существует.
Вы можете проверить это, используя пример код, который я подготовил ниже, который показывает как реализования JQuery, так и JavaScript с функцией 5-секундной функции High-CPU. Код легко следовать. Когда вы нажимаете кнопку или ссылку, вы никогда не увидите «обработка ...»
<!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>
По состоянию на 2019 каждый использует двойной requesAnimationFrame
для пропуска кадра вместо того, чтобы создать состояние состязания с помощью setTimeout.
....
function doRun() {
document.getElementById('msg').innerHTML = 'Processing JS...';
requestAnimationFrame(() =>
requestAnimationFrame(function(){
start = new Date();
end = addSecs(start,5);
do {start = new Date();} while (end-start > 0);
document.getElementById('msg').innerHTML = 'Finished Processing';
}))
}
...
У вас есть цикл, который работает в течение 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: