jQuery / JavaScript - Как ждать манипулируемого DOM, чтобы обновить, прежде чем продолжить функцию

Что я пытаюсь сделать, - это обновить простой 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>
26
задан John Conde 30 July 2012 в 12:36
поделиться

2 ответа

По состоянию на 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';   
    }))
}
...
0
ответ дан 28 November 2019 в 17:21
поделиться

У вас есть цикл, который работает в течение 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:

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

3
ответ дан 28 November 2019 в 17:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: