JS-почему такой порядок выполнения кода? (Начальный уровень)
Какова логика порядка выполнения кода JS? Я ожидал бы, что после нажатия кнопки фон станет красным, а затем появится сообщение. Однако сообщение появляется первым, и цвет применяется к фону после того, как я нажимаю OK -> CodePen. Как правильно и правильно сделать фон красным, прежде чем я нажму кнопку ОК?
function run(){
document.body.style.backgroundColor = 'red';
alert('Contratulations!');
}
<html>
<head></head>
<body>
<button onclick="run()">Click me!</button>
</body>
</html>
3 ответа:
Код выполняется в том порядке, который вы ожидаете, однако, каждый из этих операторов не является синхронным, так как они вызывают funcitonality, предоставляемую Webbrowser.
Браузер, выполняемый Javascript, не встречается в потоке пользовательского интерфейса. Поэтому, когда вы изменяете DOM (абстракцию, которая позволяет Javascript взаимодействовать с HTML браузера), он вместо этого запускает обновление пользовательского интерфейса (страницы браузера), которое происходит отдельно от выполнения javascript. Базовый элемент DOM обновляется, но существует не - мгновенное обновление до фактического пользовательского интерфейса.
В коде после изменения элемента DOM код немедленно запускает браузер для отображения предупреждения. Отображение предупреждений-это специфическое поведение браузера, и в случае Chrome оно приостанавливает обновление пользовательского интерфейса и требует, чтобы вы взаимодействовали с предупреждением, прежде чем продолжить. В Firefox предупреждение отображается после обновления пользовательского интерфейса.
Поведение между двумя браузерами-это просто разница в том, как движок визуализации браузера и реализуются циклы событий.
function run(){ document.body.style.backgroundColor = 'red'; setTimeout(function() { alert('Contratulations!'); },0 ); }
<html> <head></head> <body> <button onclick="run()">Click me!</button> </body> </html>
Этот ответ содержит немного больше информации о том, как вы можете решить проблему, Почему setTimeout(fn, 0) иногда полезен?
Вызывая
setTimeout
, вы добавляете отображениеalert
в конец цикла событий javascript, что дает пользовательскому интерфейсу достаточно времени для обновления.
Это вызвано тем, что вызов
alert()
является вызовом модального диалога . Модальный диалог-это тот, который блокирует пользовательский интерфейс от выполнения каких-либо других действий, пока диалог не будет закрыт. Это просто вопрос браузера, не отображающего цвет достаточно быстро, чтобы показать его, прежде чем среда выполнения JavaScript перейдет к следующему оператору. Важно признать, чтоalert()
на самом деле является методом объектаwindow
. Вы могли бы написатьwindow.alert()
. Зная это, вы должны понять, что объектwindow
не является родной частью языка JavaScript.window
является объектом браузера и, как таковой, управляется браузером, а не средой выполнения JavaScript.Я изменил ваш код, чтобы показать сообщение в консоли, а не предупреждение. Поскольку запись в консоль не блокирует пользовательский интерфейс, вы сразу видите изменение цвета.
function run(){ document.body.style.backgroundColor = 'red'; console.log('Contratulations!'); }
<html> <head></head> <body> <button onclick="run()">Click me!</button> </body> </html>
Попробуйте это.
function run(){ document.body.style.backgroundColor = 'red'; setTimeout(function() { alert('Contratulations!'); }, 0); }
<html> <head></head> <body> <button onclick="run()">Click me!</button> </body> </html>
setTimeout
вызывает функцию после задержки. В этом случае задержка равна нулю, позволяя фону измениться до создания предупреждения, но не создавая заметной задержки.