Andy
Andy

Reputation: 6329

Popup appears before its previous statement is executed

I am a Java developer trying to learn javascript. I have a select book dropdown from which I can select a book. On selection, I will display the following message. You have selected <selectedBook> book!

<!DOCTYPE html>
<html>
<head>
    <script>
function selectBook() {

  var selectedBook = document.getElementById("books").value;
  if (selectedBook=='select') {
    document.getElementById("displaySelectedBook").style.display = "none";
    alert("Please select a valid book");
    return;
  } 
document.getElementById("displaySelectedBook").style.display = "block";
document.getElementById("displaySelectedBook").innerHTML = "You have selected " + selectedBook.bold() + " book!";

}
</script>
</head>
<body>
<br>
<table style="width:30%" border="1" align="center">
  <tr>
    <th>Select a Book</th>
    <td>
      <select id="books" onchange="selectBook()
      ">
          <option value="select">Select</option>
          <option value="Head First Java">Head First Java</option>
          <option value="Complete Reference">Complete Reference</option>
          <option value="Gang of four">Gang of four</option>
          <option value="Effective Java">Effective Java</option>
        </select>
    </td>
  </tr>
   <tr>
  <td colspan="2" align="center" style="display: none;">
     <button type="button" onclick="selectBook()">Select!</button>
  </td>


 </tr>

</table>

<p id="displaySelectedBook"/>

</body>
</html>

The problem is when I select a valid book, say Complete Reference, and then I select "select", the expected behavior is that the para tag with ID displaySelectedBook should disappear before the alert message is displayed. But it works the other way round.

When I introduced a delay as shown below it worked fine

   setTimeout(function() {
      alert("Please select a valid book");
   }, 1);

Shouldn't the code run sequencely? Can anyone please explain the behavior here? Thanks

Upvotes: 2

Views: 167

Answers (1)

Jonas Wilms
Jonas Wilms

Reputation: 138267

Imagine this blocking js code:

  for(let i = 0; i < 1000; i++)
    document.body.innerHTML += "something";

If the browser would directly rerender every time the DOM changes, mutating the DOM would take very long and would have a great impact on performance. Therefore most browsers just rerender after javascript stops executing. alert is actually the only way to really block javascript, so it is the only case where you can really notice this behaviour.

When I introduced a delay as shown below it worked fine

Because then JS stops executing for one tick, and the browser got some time to rerender.

Different browsers behave differently here because it is actually not specified.

Upvotes: 1

Related Questions