Chrome - проблема последовательности выполнения Javascript с alert () - PullRequest
0 голосов
/ 23 октября 2018

сегодня я задумался о последовательности выполнения в Chrome для JavaScript-функции "alert ()"

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="test1">
test1 test1 test1 test1 
</div>

<div id="test2">
test2 test2 test2 test2 
</div>

<input type="button" onclick="runTest()" value="start test">

<script>

function runTest()
{
  $('#test1').css('background-color', 'red');
  alert('test1');

  $('#test2').css('background-color', 'red');
	alert('test2');
}

</script>

В Firefox 62 и IE11 (работает как ожидалось):

1) BGcolor Line 1  
2) Alertbox 1  
3) (click OK)  
4) BGcolor Line 2  
5) Alertbox 2  
6) (click OK) 

В Chrome 69.0.3497.100:

1) Alertbox 1  
2) (click OK)   
3) Alertbox 2
4) (click OK)  
5) BGcolor Line 1  
6) BGcolor Line 2  

Почему Chrome не запускает оповещение () и не ждет нажатия кнопки ОК?

Спасибо
Олли

Ответы [ 3 ]

0 голосов
/ 23 октября 2018

Проблема в том, что alert() отображается программным обеспечением браузера, а не средой выполнения JavaScript или механизмом рендеринга CSS, и часто браузер может работать быстрее / медленнее, чем может выполнять среда выполнения JavaScript.В этом случае alert визуализируется до того, как среда выполнения JavaScript и движок рендеринга CSS смогут изменить цвет фона.А поскольку alert() является модальным диалоговым окном, остальная часть пользовательского интерфейса блокируется до тех пор, пока не будет закрыто alert(), поэтому до этого вы не увидите красный фон.

Решение этой проблемычтобы вручную взять под контроль рендеринг alert(), отложив его до тех пор, пока текущая функция не будет завершена с таймером:

function runTest() {
    $('#test1').css('background-color', 'red');
    // Timer callback functions are placed in the event queue and
    // won't run until the JavaScript call stack is idle. So,
    // makeAlert("test1") won't run until after runTest(), which
    // will allow the browser to color the background red before
    // the first alert is rendered.
    setTimeout(function(){
      makeAlert("test1");
    }, 100);
}

function makeAlert(msg){
    // Now, the first background has been applied and so
    // we can ask for the first alert().
    alert(msg);
      
    // Now, we'll set the second background color
    $('#test2').css('background-color', 'red');
    
    // And defer the second alert until after this function
    // is complete.
    setTimeout(function(){
      alert("test2");
    }, 100);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="test1">test1 test1 test1 test1</div>
<div id="test2">test2 test2 test2 test2</div>

<input type="button" onclick="runTest()" value="start test">
0 голосов
/ 23 октября 2018

function runTest() {
  setTimeout(function() {
    var a = document.querySelector('#test1');
    a.style.backgroundColor = 'red';
    alert('test1');
  }, 100);

  setTimeout(function() {
    var a = document.querySelector('#test2');
    a.style.backgroundColor = 'red';
    alert('test2');
  }, 200);
  }
    <div id="test1">
        test1 test1 test1 test1
    </div>

    <div id="test2">
        test2 test2 test2 test2
    </div>
    <input type="button" onclick="runTest()" value="start test">
0 голосов
/ 23 октября 2018

Проведя небольшое исследование для подобных проблем, ответ на этот вопрос , кажется, делает его правильным:

... изменение объекта стиля запускаетсообщение запроса на перерисовку для средства визуализации страниц, которое обрабатывается, как только браузер становится бездействующим, то есть после завершения этой скриптовой процедуры.

По-видимому, это делает только Chrome.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...