#javascript
#javascript #HTML
Вопрос:
Итак, в последнее время я пробовал разные вещи и получил этот фрагмент кода в своем скрипте:
document.body.bgColor = "red";
alert("hello");
Но в Chrome сначала появляется диалоговое окно предупреждения, и только после того, как я его закрою, меняется фон моего тела. В Firefox я получаю ожидаемое поведение с изменением фона тела на красный, за которым следует всплывающее окно.
Я знаю, что мы не должны полагаться на оповещения и аналогичные элементы управления браузером, но может ли кто-нибудь сказать мне, происходит ли это потому, что поведение не соответствует стандартам, или это потому, что мое понимание синхронного выполнения приведенного выше кода неверно?
Ответ №1:
Процесс рендеринга имеет собственный жизненный цикл и не блокирует поток javascript. Они оба работают независимо.
Решение состоит в том, чтобы «приостановить» выполнение JavaScript, чтобы позволить потокам рендеринга наверстать упущенное. Это можно сделать с помощью простого setTimeout
набора 0
document.body.style.backgroundColor = "red";
setTimeout(function() {
alert("hey");
}, 0)
Обратите внимание, что bgColor
это устарело с 2003 года со спецификацией DOM Level 2. Текущий способ установки цвета фона элемента — via element.style.backgroundColor
.
Комментарии:
1. Спасибо. Это помогло. Одна вещь, которая меня беспокоит, если это гарантирует, что рендеринг завершится до
alert()
setTimeout()
выполнения inside? Я имею в виду, для более сложного CSS, есть ли событие, подобноеonStylesApplied
или что-то, что может подключиться к процессу рендеринга?2. Вы можете вызвать столько операций стиля, сколько захотите, перед
setTimeout
вызовом.3. Этот ответ неверен. Рендеринг не зависит от выполнения javascript. Оба выполняются одним и тем же потоком и оба блокируют друг друга. Предупреждение приостанавливает выполнение javascript, и рендеринг не может выполняться до тех пор, пока javascript не будет выполнен полностью. setTimeout() помещает оповещение в очередь обратного вызова, которая вызывает оповещение после рендеринга.
4. Избегайте использования a
setTimeout()
of Zero (0
) . Хотя сначала это сработало для меня, я заметил, что если я переместил мышь (сразу после нажатия кнопки, которая инициировала оповещение), изменения, которые я внес в DOM перед вызовомalert()
, все равно не будут работать. Я тестировал с10
, но в итоге пошел100
, так как он работал все время (для того, что мы делали).
Ответ №2:
Простейший обходной путь будет выглядеть так:
document.body.bgColor = "red";
setTimeout(function() {
window.alert('Hello There!');
}, 10);
Значение тайм-аута «9» является минимальным в моем случае, если я использую <9, предупреждение появляется первым.
Ответ №3:
Скорее всего, вы можете принудительно изменить цвет фона перед появлением диалогового окна, уступив на короткое время перед открытием предупреждения, что позволит браузеру перерисовать.
setTimeout(function () { alert("hello"); }, 1);