I made a small game where there are 3 pictures of chests, and you have one attempt to choose a chest with a prize. But the problem is with the asynchronous code, a notification of defeat or victory is displayed faster than the desired picture is put in the right place, After the message, a function that puts all the chests closed that also does not allow the picture to take its place.
var count=0;
var imgArray = new Array();
imgArray[0] = new Image();
imgArray[0].src ='https://i.pinimg.com/originals/ae/f7/15/aef715f93eadcdf77c4dfa3baf5859ad.jpg'
imgArray[1] = new Image();
imgArray[1].src = "https://previews.123rf.com/images/gl0ck33/gl0ck331106/gl0ck33110600002/9781614-wooden-chest-with-gold-coins.jpg";
imgArray[2] = new Image();
imgArray[2].src = "https://i.pinimg.com/originals/94/09/6b/94096bf738837c16582902d281c520bc.jpg";
var images = document.getElementsByTagName("img");
var k = Math.floor(Math.random() * 3) + 1;
console.log("Winning number " + k);
for (var i = 0; i < images.length; i++) {
images[i].addEventListener("click", function(e) {
count++;
console.log("Count " + count);
if(this.id == k){
count=0;
this.src = imgArray[1].src;//here picture with a gift
alert("You Win");// here problem,alert Faster than the picture above
TryAgain();//And this function is faster to put pictures with closed chests
return;
} else {
this.src = imgArray[0].src;//picture empty chest
}
if (count >= 1) {
count = 0;
alert("You lose!!!");//alert Faster than the picture above
TryAgain();
return;
}
}, false);
}
function TryAgain(e) {
for (var i = 0; i < images.length; i++){
images[i].src = imgArray[2].src;//picture with close chest
k = Math.floor(Math.random() * 3) + 1;
}
console.log(k);
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<img width="300px" height="300px" src="https://i.pinimg.com/originals/94/09/6b/94096bf738837c16582902d281c520bc.jpg" id="1">
<img width="300px" height="300px" src="https://i.pinimg.com/originals/94/09/6b/94096bf738837c16582902d281c520bc.jpg" id="2">
<img width="300px" height="300px" src="https://i.pinimg.com/originals/94/09/6b/94096bf738837c16582902d281c520bc.jpg" id="3">
<button id="btn" onclick="TryAgain()">Try Again</button>
</body>
</html>
2 Answers 2
Answer:
You need to wait for the images to get done loading before running alert.
alert completely halts the processing of code. Therefore if the image isn't loaded before it is executed you're not going to see the change occur.
A simple pattern to do this would be:
let self = this;
this.src = imgArray[1].src;
this.onload = function() {
alert("You Win");
self.onload = undefined;
TryAgain();
}
return;
Example:
var count=0;
var imgArray = new Array();
imgArray[0] = new Image();
imgArray[0].src ='https://i.pinimg.com/originals/ae/f7/15/aef715f93eadcdf77c4dfa3baf5859ad.jpg'
imgArray[1] = new Image();
imgArray[1].src = "https://previews.123rf.com/images/gl0ck33/gl0ck331106/gl0ck33110600002/9781614-wooden-chest-with-gold-coins.jpg";
imgArray[2] = new Image();
imgArray[2].src = "https://i.pinimg.com/originals/94/09/6b/94096bf738837c16582902d281c520bc.jpg";
var images = document.getElementsByTagName("img");
var k = Math.floor(Math.random() * 3) + 1;
console.log("Winning number " + k);
for (var i = 0; i < images.length; i++) {
images[i].addEventListener("click", function(e) {
let self = this;
count++;
console.log("Count " + count);
if(this.id == k){
count=0;
this.src = imgArray[1].src;//here picture with a gift
this.onload = function() {
alert("You Win");// here problem,alert Faster than the picture above
self.onload = undefined;
TryAgain();//And this function is faster to put pictures with closed chests
}
return;
} else {
this.src = imgArray[0].src;//picture empty chest
this.onload = function() {
alert("You Lose");// here problem,alert Faster than the picture above
self.onload = undefined;
TryAgain();//And this function is faster to put pictures with closed chests
}
return;
}
}, false);
}
function TryAgain(e) {
for (var i = 0; i < images.length; i++){
images[i].src = imgArray[2].src;//picture with close chest
k = Math.floor(Math.random() * 3) + 1;
}
console.log(k);
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<img width="300px" height="300px" src="https://i.pinimg.com/originals/94/09/6b/94096bf738837c16582902d281c520bc.jpg" id="1">
<img width="300px" height="300px" src="https://i.pinimg.com/originals/94/09/6b/94096bf738837c16582902d281c520bc.jpg" id="2">
<img width="300px" height="300px" src="https://i.pinimg.com/originals/94/09/6b/94096bf738837c16582902d281c520bc.jpg" id="3">
<button id="btn" onclick="TryAgain()">Try Again</button>
</body>
</html>
2 Comments
setTimeout(function() { alert("You Win"); TryAgain(); }, 100); By the way, it worksonload in this way in any kind of prod environment, but for learning/fun it's fine.Images do not appear as soon as you set this.src
They appear when the browser is ready to show them, which may take some time. Perhaps you can use the "load" event listener? This will fire once the image is visible. At that stage you can do the alert?
images[i].addEventListener("load", function(e) {
// This will run only once the image is loaded (i.e. visible)
} )
7 Comments
setTimeout(function() { alert("You Win"); TryAgain(); }, 100); By the way, it works
alert("You Win"); then this.src=imgArray[1].src;but not thisthis.src=imgArray[1].src; alert("You Win");