Event handling onclick Body response in every object - javascript

There is a pattern game in which the user is supposed to find 1 missed picture from right side while the location is shown on left, then if the user guessed correctly they will go to the next level.
My problem is that, even though I clicked on correct picture, the popup for wrong choice is appearing after the first iteration.
I tried to define body as the initial child but still popup is displaying regardless of correct or wrong choice.
var numberOfFaces = 5;
var theLeftSide = document.getElementById("leftSide");
var theRightSide = document.getElementById("rightSide");
var theBody = document.getElementsByTagName("body")[0];
function generateFaces() {
for (var i = 0; i < numberOfFaces; i++) {
var createImg = document.createElement("IMG");
var randPositionTop = Math.floor(Math.random() * 400);
var randPositionleft = Math.floor(Math.random() * 400);
createImg.setAttribute("src", "http://home.cse.ust.hk/~rossiter/mooc/matching_game/smile.png");
createImg.style.top = randPositionTop + "px";
createImg.style.left = randPositionleft + "px";
theLeftSide.appendChild(createImg);
}
var leftSideImages = theLeftSide.cloneNode(true);
leftSideImages.removeChild(leftSideImages.lastChild);
theRightSide.appendChild(leftSideImages);
theLeftSide.lastChild.onclick =
function nextLevel(event) {
event.stopPropagation;
numberOfFaces += 5;
alert("Next level!");
while (theLeftSide.firstChild) {
theLeftSide.removeChild(theLeftSide.firstChild);
}
generateFaces();
}
theBody.onclick =
function gameOver() {
theBody.onclick = null;
theLeftSide.lastChild.onclick = null;
alert("Game Over!");
};
}
#leftSide {
background-color: red;
position: absolute;
width: 500px;
height: 500px;
left: 50px;
}
#rightSide {
position: absolute;
left: 600px;
width: 500px;
height: 500px;
--border-left: solid 10px;
}
img {
position: absolute;
width: 50px;
height: 50px;
}
<link rel="stylesheet" href="style.css">
<body onload="generateFaces()">
<h3>Matching Game</h3>
<h5>Please choose missed smile !</h5>
<div id="leftSide">
</div>
<div id="rightSide">
</div>
<script src="jsCode.js"></script>
</body>

Updated your fiddle. Is this how you want it?
https://jsfiddle.net/ychq5rkm/12/
Specifically it uses document.ready() in the js instead of in the onload in the html. As was mentioned in the comments, you needed to actually call event.stopPropegation() because it was continuing up to the body each time and ending your game.

Related

my matching game does not work properly

I am learning JS and I'm making a game where I have to find the intruder.
my matching game does not work properly, because the faces on the left side must be incremetate of 5, because my code increases by 10?
<!DOCTYPE html>
<html>
<head>
<title>Matching Game</title>
<meta name="author" content="Aurora Ruggieri">
<style>
img{
position: absolute;
height: 100px;
width: 100px;
}
div{
position: absolute;
width: 500px;
height: 500px;
}
#rightSide {
left: 500px;
border-left: 1px solid black;
}
</style>
</head>
<body onload="generateFaces()">
<h1>Matching Game</h1>
<p>Click on the extra smiling face on the left</p>
<div id="leftSide"></div>
<div id="rightSide"></div>
<script>
var numberOfFaces = 5;
var theLeftSide = document.getElementById("leftSide");
var theRightSide = document.getElementById("rightSide");
function generateFaces(){
for (i= 0; i < numberOfFaces; i++) {
var top_position= Math.floor(Math.random() * 401);
var left_position= Math.floor(Math.random() * 401);
var leftSideImage = document.createElement("img");
leftSideImage.setAttribute("src", "http://home.cse.ust.hk/~rossiter/mooc/matching_game/smile.png");
leftSideImage.style.top = top_position + "px";
leftSideImage.style.left = left_position + "px";
theLeftSide.appendChild(leftSideImage);
var leftImages = theLeftSide.cloneNode(true);
leftImages.removeChild(leftImages.lastChild);
theRightSide.appendChild(leftImages);
}
var theBody = document.getElementsByTagName("body")[0];
theLeftSide.lastChild.onclick = function nextLevel(event){
event.stopPropagation();
while(theLeftSide.firstchild) {
theLeftSide.removeChild(theLeftSide.firstchild);
}
while(theRightSide.firstchild) {
theRightSide.removeChild(theRightSide.firstchild);
}
numberOfFaces += 5;
generateFaces();
};
theBody.onclick = function gameOver() {
alert("Game Over!");
theBody.onclick = null;
theLeftSide.lastChild.onclick = null;
};
}
</script>
</body>
</html>
Thanks in advance
If you're trying to add 5 more faces each round, remove the following line of code:
numberOfFaces += 5;
How it works currently is, first round has 5 faces, next round will add 10 more, then 15 more, then 20 more, etc..
Run this provided snippet and you will see that removing that one line of code makes it work how you want.
var numberOfFaces = 5;
var theLeftSide = document.getElementById("leftSide");
var theRightSide = document.getElementById("rightSide");
function generateFaces(){
for (i= 0; i < numberOfFaces; i++) {
var top_position= Math.floor(Math.random() * 401);
var left_position= Math.floor(Math.random() * 401);
var leftSideImage = document.createElement("img");
leftSideImage.setAttribute("src", "http://home.cse.ust.hk/~rossiter/mooc/matching_game/smile.png");
leftSideImage.style.top = top_position + "px";
leftSideImage.style.left = left_position + "px";
theLeftSide.appendChild(leftSideImage);
var leftImages = theLeftSide.cloneNode(true);
leftImages.removeChild(leftImages.lastChild);
theRightSide.appendChild(leftImages);
}
var theBody = document.getElementsByTagName("body")[0];
theLeftSide.lastChild.onclick = function nextLevel(event){
event.stopPropagation();
while(theLeftSide.firstchild) {
theLeftSide.removeChild(theLeftSide.firstchild);
}
while(theRightSide.firstchild) {
theRightSide.removeChild(theRightSide.firstchild);
}
generateFaces();
};
theBody.onclick = function gameOver() {
alert("Game Over!");
theBody.onclick = null;
theLeftSide.lastChild.onclick = null;
};
}
generateFaces();
img{
position: absolute;
height: 100px;
width: 100px;
}
div{
position: absolute;
width: 500px;
height: 500px;
}
#rightSide {
left: 500px;
border-left: 1px solid black;
}
<h1>Matching Game</h1>
<p>Click on the extra smiling face on the left</p>
<div id="leftSide"></div>
<div id="rightSide"></div>
Kyle Richardson, thanks for the reply. The game has to increase by 5 faces whenever you find the intruder,next round will add 5 more, then 5 more...

Uncaught TypeError: Cannot read property 'lastChild' of null

<!DOCTYPE html>
<html>
<head>
<title>Face Matching Game</title>
<h2>Matching Game</h2>
<p>Click on the EXTRA face on the left side</p>
<style type="text/css">
div { position: absolute; width: 640px; height: 550px; background-color: maroon }
img { position: absolute; width: 100px; height: 100px}
#rightSide { left: 650px; border-left: 2px solid black; }
</style>
<script type="text/javascript">
var NUM_OF_FACES = 0;
var THE_LEFT_SIDE, THE_RIGHT_SIDE;
//Function to generate faces
function generateFaces() {
THE_LEFT_SIDE = document.getElementById("leftSide");
THE_RIGHT_SIDE = document.getElementById("rightSide");
NUM_OF_FACES += 5;
var image;
while(NUM_OF_FACES>0){
image = document.createElement("img");
image.src = "smile.png";
image.style.top = Math.floor(Math.random()* (THE_LEFT_SIDE.offsetHeight - 100)) + "px";
image.style.left = Math.floor(Math.random()* (THE_LEFT_SIDE.offsetWidth - 100)) + "px";
THE_LEFT_SIDE.appendChild(image);
NUM_OF_FACES -= 1;
//console.log(image.style.top, image.style.left )
}
var leftSideImages = THE_LEFT_SIDE.cloneNode(true);
leftSideImages.removeChild(leftSideImages.lastChild);
THE_RIGHT_SIDE.appendChild(leftSideImages);
}//end generatefaces()
function deleteFaces(argument) {
while(THE_LEFT_SIDE.firstChild){
THE_LEFT_SIDE.removeChild(THE_LEFT_SIDE.firstChild);
}
while(THE_RIGHT_SIDE.firstChild){
THE_RIGHT_SIDE.removeChild(THE_RIGHT_SIDE.firstChild);
}
}//end deleteFaces()
var theBody = document.getElementsByTagName("body")[0];
THE_LEFT_SIDE = document.getElementById("leftSide");
THE_RIGHT_SIDE = document.getElementById("rightSide");
//Event handling
THE_LEFT_SIDE.lastChild.onclick = function goToNextLevel() {
alert("You clicked on correct face.");
deleteFaces();
generatefaces();
};
theBody.onclick = function gameOver() {
alert("Game Over!!");
theBody.onclick = null;
THE_LEFT_SIDE.lastChild.onclick = null;
};
</script>
</head>
<body onload="generateFaces()">
<div id="leftSide"></div>
<div id="rightSide"></div>
</body>
</html>
I am beginner in Javascript and ran into a problem while doing an assignment.
It is Fact Matching game and you have to click the extra face on the left side and game continues until you click somewhere else than extra face on left.
Above is the HTML file and JS code is embedded in it.
I am getting an error as: Uncaught TypeError: Cannot read property 'lastChild' of null at line number 48, which is onclick event handler function on lastChild of THE_LEFT_SIDE div. I don't know how it is coming and what is the problem with my code?
Any leads will be appreciated.
You are trying to access the element with id leftSide before it has been added to the DOM.
If you move your script to the end of the page body, you will no longer see this error, but a different, unrelated one instead:
<!DOCTYPE html>
<html>
<head>
<title>Face Matching Game</title>
<h2>Matching Game</h2>
<p>Click on the EXTRA face on the left side</p>
<style type="text/css">
div { position: absolute; width: 640px; height: 550px; background-color: maroon }
img { position: absolute; width: 100px; height: 100px}
#rightSide { left: 650px; border-left: 2px solid black; }
</style>
</head>
<body onload="generateFaces()">
<div id="leftSide"></div>
<div id="rightSide"></div>
<script type="text/javascript">
var NUM_OF_FACES = 0;
var THE_LEFT_SIDE, THE_RIGHT_SIDE;
//Function to generate faces
function generateFaces() {
THE_LEFT_SIDE = document.getElementById("leftSide");
THE_RIGHT_SIDE = document.getElementById("rightSide");
NUM_OF_FACES += 5;
var image;
while(NUM_OF_FACES>0){
image = document.createElement("img");
image.src = "smile.png";
image.style.top = Math.floor(Math.random()* (THE_LEFT_SIDE.offsetHeight - 100)) + "px";
image.style.left = Math.floor(Math.random()* (THE_LEFT_SIDE.offsetWidth - 100)) + "px";
THE_LEFT_SIDE.appendChild(image);
NUM_OF_FACES -= 1;
//console.log(image.style.top, image.style.left )
}
var leftSideImages = THE_LEFT_SIDE.cloneNode(true);
leftSideImages.removeChild(leftSideImages.lastChild);
THE_RIGHT_SIDE.appendChild(leftSideImages);
}//end generatefaces()
function deleteFaces(argument) {
while(THE_LEFT_SIDE.firstChild){
THE_LEFT_SIDE.removeChild(THE_LEFT_SIDE.firstChild);
}
while(THE_RIGHT_SIDE.firstChild){
THE_RIGHT_SIDE.removeChild(THE_RIGHT_SIDE.firstChild);
}
}//end deleteFaces()
var theBody = document.getElementsByTagName("body")[0];
THE_LEFT_SIDE = document.getElementById("leftSide");
THE_RIGHT_SIDE = document.getElementById("rightSide");
//Event handling
THE_LEFT_SIDE.lastChild.onclick = function goToNextLevel() {
alert("You clicked on correct face.");
deleteFaces();
generatefaces();
};
theBody.onclick = function gameOver() {
alert("Game Over!!");
theBody.onclick = null;
THE_LEFT_SIDE.lastChild.onclick = null;
};
</script>
</body>
</html>

Matching Game. Javascript. DOM lastChild

There is a simple game. The left and right sides are identical, except for one thing: the left side has one extra face. The user needs to find out and click on that extra face (lastChild). It will trigger the function to double the face quantity.
The problem is - all the faces in my game are lastChild. Where is the problem?
Thanks!
<!DOCTYPE <!DOCTYPE html>
<html>
<head>
<title>Matching Game. Part 3.</title>
<style>
img {
position: absolute;
}
div {
position: absolute;
width: 500px;
height: 500px;
}
#rightSide {
left: 500px;
border-left: 1px solid black;
}
</style>
<script>
function generateFaces(){
var numberOfFaces = 5;
//var theLeftSide = document.getElementById("leftSide");
for(var i=0; i < numberOfFaces; i++) {
var smileImage = document.createElement("img");
smileImage.src="http://home.cse.ust.hk/~rossiter/mooc/matching_game/smile.png";
var topPosition = Math.floor(Math.random()* 400) + 1;
var leftPosition = Math.floor(Math.random()* 400) + 1;
smileImage.style.top = topPosition + "px";
smileImage.style.left = leftPosition + "px";
leftSide.appendChild(smileImage);
var leftSideImages = leftSide.cloneNode(true);
leftSideImages.removeChild(leftSideImages.lastChild);
rightSide.appendChild(leftSideImages);
leftSide.lastChild.style.background = "red";
var theBody = document.getElementsByTagName("body")[0];
leftSide.lastChild.onclick = function nextLevel(event) {
event.stopPropagation();
numberOfFaces += 5;
generateFaces();
}
}
}
</script>
</head>
<body onload = "generateFaces()">
<h1>Matching Game</h1>
<p>Click on the extra smiling face on the left.</p>
<div id="leftSide"></div>
<div id="rightSide"></div>
</body>
</html>
You are binding your click event to every element in the loop. You first need to over-ride the previous handler and then re-bind it to the last element.
function generateFaces(){
var numberOfFaces = 5;
var leftSide = document.getElementById("leftSide");
var rightSide = document.getElementById("rightSide");
for(var i=0; i < numberOfFaces; i++) {
var smileImage = document.createElement("img");
smileImage.src="http://home.cse.ust.hk/~rossiter/mooc/matching_game/smile.png";
var topPosition = Math.floor(Math.random()* 400) + 1;
var leftPosition = Math.floor(Math.random()* 400) + 1;
smileImage.style.top = topPosition + "px";
smileImage.style.left = leftPosition + "px";
leftSide.appendChild(smileImage);
var leftSideImages = leftSide.cloneNode(true);
leftSideImages.removeChild(leftSideImages.lastChild);
rightSide.appendChild(leftSideImages);
leftSide.lastChild.style.background = "red";
var theBody = document.getElementsByTagName("body")[0];
}
var pics = document.getElementsByTagName("img");
for(i=0;i<pics.length;i++){
pics[i].onclick = function() {
return false;
}
}
leftSide.lastChild.onclick = function nextLevel(event) {
event.stopPropagation();
numberOfFaces += 5;
generateFaces();
}
}
img {
position: absolute;
}
div {
position: absolute;
width: 500px;
height: 500px;
}
#rightSide {
left: 500px;
border-left: 1px solid black;
}
<body onload = "generateFaces()">
<h1>Matching Game</h1>
<p>Click on the extra smiling face on the left.</p>
<div id="leftSide"></div>
<div id="rightSide"></div>
</body>

Using on click vanilla JS, activating on wrong node

Almost finished this sort of game i am working on to learn Dom manipulation. Basically the game spawns 5 images on the left and 4 on the right, you click the odd one out and then 10 spawn on the left and 9 on the right(+5 everytime).
I am wanting my nextlevel function to work every time the last child(of theLeftSide) is clicked on. It works the first time but after that regardless of if i click the correct node or not, my gameOver function is called and im not sure why. I tried removing the game over function and still the 2nd time i want my nextLevel to run(after click), it doesnt. Am i going about this the totally wrong way? Any input is appreciated thank you. Left my gameOver function in so you can see what im trying to do with it.
var theLeftSide = document.getElementById("leftside");
var theRightSide = document.getElementById("rightside");
var facesNeeded = 5;
var totalfFaces = 0;
var theBody = document.getElementsByTagName("body")[0];
function makeFaces() {
while (facesNeeded != totalfFaces) {
smiley = document.createElement("img");
smiley.src = "http://home.cse.ust.hk/~rossiter/mooc/matching_game/smile.png";
smiley.style.top = Math.random() * 401 + "px";
smiley.style.left = Math.random() * 401 + "px";
document.getElementById("leftside").appendChild(smiley);
totalfFaces++;
// alert(totalfFaces); used to debug
}
if (facesNeeded == totalfFaces) {
//alert(facesNeeded);
//alert(totalfFaces);
leftSideImages = theLeftSide.cloneNode(true);
leftSideImages.removeChild(leftSideImages.lastChild);
document.getElementById("rightside").appendChild(leftSideImages);
//alert("hi");
}
}
makeFaces();
function delFaces(side) {
while (side.firstChild) {
side.removeChild(side.firstChild);
}
}
theLeftSide.lastChild.onclick = function nextLevel(event) {
event.stopPropagation();
delFaces(theRightSide);
delFaces(theLeftSide);
totalfFaces = 0;
facesNeeded += 5;
//alert(facesNeeded);
//alert(totalfFaces);
makeFaces();
};
theBody.onclick = function gameOver() {
alert("Game Over!");
theBody.onclick = null;
theLeftSide.lastChild.onclick = null;
};
<!DOCTYPE html>
<html>
<head>
<style>
img {
position: absolute;
}
div {
position: absolute;
width: 500px;
height: 500px;
}
#rightside {
left: 500px;
border-left: 1px solid black;
}
</style>
</head>
<body>
<h1> Matching Game</h1>
<p>Click on the extra smiling face on the left</p>
<div id="leftside"></div>
<div id="rightside"></div>
<script src="script3.js"></script>
</body>
</html>
You just need to move the onclick inside the makeFaces after the while, so its added everytime after it creates them all:-
var theLeftSide = document.getElementById("leftside");
var theRightSide = document.getElementById("rightside");
var facesNeeded = 5;
var totalfFaces = 0;
var theBody = document.getElementsByTagName("body")[0];
function makeFaces() {
while (facesNeeded != totalfFaces) {
smiley = document.createElement("img");
smiley.src = "http://home.cse.ust.hk/~rossiter/mooc/matching_game/smile.png";
smiley.style.top = Math.random() * 401 + "px";
smiley.style.left = Math.random() * 401 + "px";
document.getElementById("leftside").appendChild(smiley);
totalfFaces++;
// alert(totalfFaces); used to debug
}
if (facesNeeded == totalfFaces) {
//alert(facesNeeded);
//alert(totalfFaces);
leftSideImages = theLeftSide.cloneNode(true);
leftSideImages.removeChild(leftSideImages.lastChild);
document.getElementById("rightside").appendChild(leftSideImages);
//alert("hi");
}
theLeftSide.lastChild.onclick = function nextLevel(event) {
event.stopPropagation();
delFaces(theRightSide);
delFaces(theLeftSide);
totalfFaces = 0;
facesNeeded += 5;
//alert(facesNeeded);
//alert(totalfFaces);
makeFaces();
};
}
makeFaces();
function delFaces(side) {
while (side.firstChild) {
side.removeChild(side.firstChild);
}
}
theBody.onclick = function gameOver() {
alert("Game Over!");
theBody.onclick = null;
theLeftSide.lastChild.onclick = null;
};
<!DOCTYPE html>
<html>
<head>
<style>
img {
position: absolute;
}
div {
position: absolute;
width: 500px;
height: 500px;
}
#rightside {
left: 500px;
border-left: 1px solid black;
}
</style>
</head>
<body>
<h1> Matching Game</h1>
<p>Click on the extra smiling face on the left</p>
<div id="leftside"></div>
<div id="rightside"></div>
<script src="script3.js"></script>
</body>
</html>

Can't animate div #box using Javascript

Help! I've no idea what's going wrong here, I'm following along a tutorial video from Tuts+ The code is exact, yet the blue box is not animating to the left.
When I put an alert inside of the moveBox function, I see in the console the alert firing off the same message over and over again.
Here is my test link:
> Trying to animation a blue box left using Javascript <
Here is a screenshot from the video:
Here is my code:
(function() {
var speed = 10,
moveBox = function() {
var el = document.getElementById("box"),
i = 0,
left = el.offsetLeft,
moveBy = 3;
//console.log("moveBox executed " +(i+1)+ " times");
el.style.left = left + moveBy + "px";
if (left > 399) {
clearTimeout(timer);
}
};
var timer = setInterval(moveBox, speed);
}());
HTML:
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<title>JavaScript 101 : Window Object</title>
<style>
#box {
position: abosolute;
height: 100px;
left: 50px;
top: 50px;
width: 100px;
background-color: Blue;
}
</style>
</head>
<body>
<div id="box"></div>
<script src="js/animation.js"></script>
You mispelled "absolute" in your positioning:
#box {
position: absolute; // Your mispelling here
height: 100px;
left: 50px;
top: 50px;
width: 100px;
background-color: Blue;
}
Once I fixed that, it worked fine.
A word of advice -- put a second condition in loops like this so that if the animation fails for some reason you don't end up in an infinite loop. For example, you might have done this:
(function() {
var maxTimes = 1000;
var loopTimes = 0;
var speed = 10,
moveBox = function() {
var el = document.getElementById("box"),
i = 0,
left = el.offsetLeft,
moveBy = 3;
//console.log("moveBox executed " +(i+1)+ " times");
el.style.left = left + moveBy + "px";
loopTimes += 1;
if (left > 399 || loopTimes > maxTimes) {
clearTimeout(timer);
}
};
var timer = setInterval(moveBox, speed);
}());

Categories

Resources