I'm working on Rock/Paper/Scissors game for the Odin Project. I display the result of a game in a div resultMsg, and a running tally based on that result in countMsg. Both those items are divs in the HTML and they work correctly. After a total of 5 games are won or lost, I want to (in order) clear the textContent messages, use an "alert" to give a final tally, and start over.
I expected that the two lines highlighted with "->" would clear the textContent message. However they do not until after I click [OK] to clear the alert. I'd really like to understand why that is.
The HTML relevant body:
<div id="playersChoice">
<button id='rock'>Rock</button>
<button id='paper'>Paper</button>
<button id='scissors'>Scissors</button>
</div>
<div id="result">
</div>
<div id="count">
</div>
The Javascript that's relevant.
let gamesPlayed = 0;
let playerWon = 0;
let computerWon = 0;
const countMsg = document.querySelector ('#count');
const resultMsg = document.querySelector ('#result');
// Get all the buttons within playerschoice container
const userButton = document.querySelectorAll ('#playersChoice > button');
// For each button, create an event listener for the click which will play a round.
// Note the Button.ID identifies the players choice.
userButton.forEach(button => {
button.addEventListener('click', function() {
gamesPlayed++;
resultMsg.textContent = playRound(button.id, computerPlay());
// if there are less than 5 clear wins or losses
if ((playerWon + computerWon) < 5) {
countMsg.textContent = "The current tally is your " + playerWon + " wins to the computers " + computerWon + ".";
} else {
// there have been 5 definitive games, declare the overall winner!
-> resultMsg.textContent = '';
-> countMsg.textContent = '';
gamesPlayed = 0;
playerWon = 0;
computerWon = 0;
alert("Best of 5 series results : You won " + playerWon +", lost " + computerWon + ", and tied "+ (5-playerWon-computerWon) + " of them.");
}
});
});
'''
alert() will block the current script execution, but it seems to also blocks the DOM update. That's why even though the assignement to textContent is before the alert, the text is only shown after the alert has been clicked, and the execution has resumed.
You can use a very small setTimeout to allow the DOM to update before the alert() fires:
const div = document.querySelector("div");
function test1() {
div.textContent = "Test without timeout!";
alert("Test1!");
}
function test2() {
div.textContent = "Test with timeout!";
setTimeout(() => alert("Test2!"), 10);
}
<button onclick="test1()">Test</button>
<button onclick="test2()">Test with timeout</button>
<h4>Text content:</h4>
<div></div>
Edit:
I researched a bit more, and to be more precise, DOM updates happen only after the script has finished. Since alert() blocks the current script, the DOM update will only happen after the alert has been dismissed.
This behavior can also be seen with the following snippet:
function wait(ms) {
var start = Date.now(),
now = start;
while (now - start < ms) {
now = Date.now();
}
}
function test() {
document.querySelector("div").textContent = "Test with delay!";
wait(2000);
}
<button onclick="test()">Test with delay</button>
<div></div>