0

var map = [0,0,0,0,0,0,0,0,0],  // Array for the Game and the the Win Check
    design = ["td0", "td1", "td2", 
           "td3", "td4", "td5", 
           "td6", "td7", "td8"], // Array for the fields of the Table.
    Player = true; // true is player Blue, false is player red. 

function Game(x) // Game() will be executed when a field in the Table is clicked.
{
  switch(Player) // Switch from Player 1 to 2 
    {
      case true:
        if(map[x] == 0) // this if is for 
        {
            document.getElementById(design[x]).style.backgroundColor = "blue";
            map[x] = 1; // in the 'map' array 1 are Player Blue fields and 2 are Player Red fields
            Check(1); // The Win Check for the Game
            Player = false; // PlayerChange to Player 1 or 'Red'
        }
        break;
      case false:
        if(map[x] == 0)
        {
            document.getElementById(design[x]).style.backgroundColor = "red";
            map[x] = 2; 
            Check(2);
            Player = true; // PlayerChange to Player 2 or 'Blue'
        }
     }
}

function Check(x)
{
 if(map[0] == x && map[1] == x && map[2] == x || // horizontal 
     map[3] == x && map[4] == x && map[5] == x || // ^
    map[6] == x && map[7] == x && map[8] == x || // ^
    map[0] == x && map[3] == x && map[6] == x || // vertical
    map[1] == x && map[4] == x && map[7] == x || // ^
    map[3] == x && map[5] == x && map[8] == x || // ^
    map[0] == x && map[4] == x && map[8] == x || // diagonal
    map[2] == x && map[4] == x && map[6] == x)   // ^
  {
   
     alert("Player " + x + " win!"); // Alert for the Player
        
          for(var i=0;i<9;i++) 
          {
            map[i] == 3; // Makes the fields untouchable from User.
          }    
  }
}
td
{
  height: 100px;
  width: 100px;
  border: 1px solid black;
}
<html>
  <head>
    
  </head>
  <body>
    <table>
      <tr>
        <td id="td0" onclick="Game(0);" />
        <td id="td1" onclick="Game(1);" />
        <td id="td2" onclick="Game(2);" />
      </tr>
      <tr>
        <td id="td3" onclick="Game(3);" />
        <td id="td4" onclick="Game(4);" />
        <td id="td5" onclick="Game(5);" />
      </tr>
      <tr>
        <td id="td6" onclick="Game(6);" />
        <td id="td7" onclick="Game(7);" />
        <td id="td8" onclick="Game(8);" />
      </tr>
     </table>
  </body>
<html>
My Problem is here, that I don't know/understand why the Check (with the Alert) is executed before the document.getElementById("id").style.backgroundColor = "color", which is 2 lines above this function.
Garf365
  • 3,619
  • 5
  • 29
  • 41
  • It doesn't. If you put it in the debugger, it happens as you would expect. Is is that you're expecting the colour to change before the alert is displayed? – deadwards Sep 07 '16 at 07:41
  • Is it though? Have you logged to your console to seeif that is true a sit does not necessarily have to be true. Also, if you are checking true/falseyouare better of usingan if than a switch. – somethinghere Sep 07 '16 at 07:42
  • Because of the asynchronous nature of JavaScript. See [this](http://stackoverflow.com/questions/4559032/easy-to-understand-definition-of-asynchronous-event). – casual Sep 07 '16 at 07:42
  • 1
    It isn't executed before ... it's in the nature of (single-threaded) Javascript that changes in the GUI can only be shown after the program flow has become idle. So it seems like the color changes only after the alert shows. To prevent this, you could call the "Check" function with a 0ms timeout like `setTimeout(function(){Check(1);}, 0)`. That should do the trick – devnull69 Sep 07 '16 at 07:43
  • 4
    @casual its more about the synchronous nature of javascript though :) – somethinghere Sep 07 '16 at 07:45
  • While this is a nice game sample, a shorter, more simplified code sample that demonstrates this effect would be better for the purpose of this question. – deceze Sep 07 '16 at 07:50

2 Answers2

0

As recommended, I added a dealy to you alert, because GUI-Updates take some time.

var map = [0,0,0,0,0,0,0,0,0],  // Array for the Game and the the Win Check
    design = ["td0", "td1", "td2", 
           "td3", "td4", "td5", 
           "td6", "td7", "td8"], // Array for the fields of the Table.
    Player = true; // true is player Blue, false is player red. 

function Game(x) // Game() will be executed when a field in the Table is clicked.
{
  switch(Player) // Switch from Player 1 to 2 
    {
      case true:
        if(map[x] == 0) // this if is for 
        {
            document.getElementById(design[x]).style.backgroundColor = "blue";
            map[x] = 1; // in the 'map' array 1 are Player Blue fields and 2 are Player Red fields
            Check(1); // The Win Check for the Game
            Player = false; // PlayerChange to Player 1 or 'Red'
        }
        break;
      case false:
        if(map[x] == 0)
        {
            document.getElementById(design[x]).style.backgroundColor = "red";
            map[x] = 2; 
            Check(2);
            Player = true; // PlayerChange to Player 2 or 'Blue'
        }
     }
}

function Check(x)
{
 if(map[0] == x && map[1] == x && map[2] == x || // horizontal 
     map[3] == x && map[4] == x && map[5] == x || // ^
    map[6] == x && map[7] == x && map[8] == x || // ^
    map[0] == x && map[3] == x && map[6] == x || // vertical
    map[1] == x && map[4] == x && map[7] == x || // ^
    map[3] == x && map[5] == x && map[8] == x || // ^
    map[0] == x && map[4] == x && map[8] == x || // diagonal
    map[2] == x && map[4] == x && map[6] == x)   // ^
  {
   
     setTimeout(function(){alert("Player " + x + " win!")}, 100);; // Alert for the Player
        
          for(var i=0;i<9;i++) 
          {
            map[i] == 3; // Makes the fields untouchable from User.
          }    
  }
}
td
{
  height: 100px;
  width: 100px;
  border: 1px solid black;
}
<html>
  <head>
    
  </head>
  <body>
    <table>
      <tr>
        <td id="td0" onclick="Game(0);" />
        <td id="td1" onclick="Game(1);" />
        <td id="td2" onclick="Game(2);" />
      </tr>
      <tr>
        <td id="td3" onclick="Game(3);" />
        <td id="td4" onclick="Game(4);" />
        <td id="td5" onclick="Game(5);" />
      </tr>
      <tr>
        <td id="td6" onclick="Game(6);" />
        <td id="td7" onclick="Game(7);" />
        <td id="td8" onclick="Game(8);" />
      </tr>
     </table>
  </body>
<html>
Tobias S
  • 1,275
  • 8
  • 23
  • 2
    It is not that "GUI updates take some time" it is that GUI refresh is implementation specific, and the major browser do it at the end of an iteration of the event loop, not meanwhile. You could do some lengthy task and still see no update until the flow reach the end of the event loop. – Margaret Bloom Sep 07 '16 at 07:47
0

While your Javascript code runs, the UI does not update; in fact the entire page is blocked until your code has finished. Only then is control returned to the browser and the UI updates. You can make thousands of style changes to elements in Javascript, they will all be applied atomically at the end of the script.

Only an explicit alert is a bit of an exception in that it needs to happen right now, so it will suspend your script, pop up the dialog, and then resume your script when it's closed.

To return control to the browser to update its UI and then pop up an alert, use setTimeout to display the alert; the delay can be 0, all that matters is that the control is returned to the browser for a moment.

deceze
  • 510,633
  • 85
  • 743
  • 889