Quiz won’t continue - javascript

My quiz is getting caught and won’t pass through on to the next question when the right answer is given.
//loop through questions when right answer is given
function questFunc() {
"use strict";
//create array with my questions
var qArray = ["What is the answer to the sum 1 + 1?", "If I have two eggs and I drop one how many do I have left?", "What are the three primary colors?"];
var aArray = ["2", "1", "What are the three primary colors?"];
//create variables
var pageCounter = 1;
var qCounter = 0;
var aCounter = 0;
var theQuestions = document.getElementById("theQuestions");
var pageNum = document.getElementById("pageNum");
var theAnswer = document.getElementById("theAnswer").value;
if (qCounter < qArray.length) {
theQuestions.innerHTML = qArray[qCounter];
pageNum.innerHTML = pageCounter;
//not working - not allowing questions to move on when right answer is given.
if (theAnswer === aArray[aCounter]) {
qCounter++;
aCounter++;
pageCounter++;
}
} else if (qCounter >= qArray.length) {
theQuestions.innerHTML = "Well Done!";
pageNum.style.display = "none";
}
}
<div>
<h1 id="quizTitle">My JavaScript Quiz
</h1>
<p id="theQuestions">Click NEXT to start quiz..
</p>
<form id="" action="#" method="post">
<!-- Form Needs Columns -->
<div id="">
<label for="theAnswer"></label>
<input type="text" id="theAnswer" tabindex="1">
</div>
</form>
<span id="pageNum">
</span>
<button onclick="questFunc()">NEXT</button>
</div>

You're calling questFunc from the "Next" button, but all of your state is local to that function. So all of your state is recreated every time the function is called.
Instead, move the state that isn't specific to the function call out of the function. Since globals are a Bad Thing™, we'll do that by wrapping all our state (and the function) in a scoping function, and then use modern event handling to hook it up instead of onclick. (onxyz-attribute-style event handlers can only call global functions. It's one of the many reasons not to use them.)
So our scoping function, just to keep things contained, is:
(function() {
// Our code here
})();
...and our button is:
<button id="next-button">NEXT</button>
...and we hook it up using addEventListener:
document.getElementById("next-button").addEventListener("click", questFunc);
(See this answer if you need to support obsolete versions of IE.)
See the snippet for what state I moved out of the function, and see the comments for some other notes:
(function() {
"use strict";
var qArray = ["What is the answer to the sum 1 + 1?", "If I have two eggs and I drop one how many do I have left?", "What are the three primary colors?"];
var aArray = ["2", "1", "What are the three primary colors?"]; // Third answer looks like a copy-and-paste error
// We only need one counter, and let's start it at -1 because the first click
// starts the quiz
var counter = -1;
var theQuestions = document.getElementById("theQuestions");
var pageNum = document.getElementById("pageNum");
// Might as well get the answer field too
var theAnswer = document.getElementById("theAnswer");
// Hook up the button
document.getElementById("next-button").addEventListener("click", questFunc);
function questFunc() {
// Get their answer (if any)
var answer = theAnswer.value.trim(); // trim just to strip leading/trailing spaces
// If we're just starting the quiz or they answered correctly, show the next
if (counter == -1 || answer === aArray[counter]) {
counter++;
if (counter >= qArray.length) {
// Done with quiz
theQuestions.innerHTML = "Well Done!";
pageNum.style.display = "none";
} else {
// Show the now-current question
theQuestions.innerHTML = qArray[counter];
pageNum.innerHTML = (counter + 1);
}
// Always clear the answer
theAnswer.value = "";
} else {
// Incorrect answer, probably worth saying something here
}
}
})();
<div>
<h1 id="quizTitle">My JavaScript Quiz
</h1>
<p id="theQuestions">Click NEXT to start quiz..
</p>
<form id="" action="#" method="post">
<!-- Form Needs Columns -->
<div id="">
<label for="theAnswer"></label>
<input type="text" id="theAnswer" tabindex="1">
</div>
</form>
<span id="pageNum">
</span>
<button id="next-button">NEXT</button>
</div>

Your counters are within the function: "Double click next".
//loop through questions when right answer is given
var pageCounter = 1;
var qCounter = 0;
var aCounter = 0;
var qArray = ["What is the answer to the sum 1 + 1?","If I have two eggs and I drop one how many do I have left?","What are the three primary colors?"];
var aArray = ["2","1","What are the three primary colors?"];
function questFunc() {
var theQuestions = document.getElementById("theQuestions");
var pageNum = document.getElementById("pageNum");
var theAnswer = document.getElementById("theAnswer").value;
if (qCounter < qArray.length) {
theQuestions.innerHTML = qArray[qCounter];
pageNum.innerHTML = pageCounter;
//not working - not allowing questions to move on when right answer is given.
if (theAnswer === aArray[aCounter]) {
qCounter++;
aCounter++;
pageCounter++;
}
} else if (qCounter >= qArray.length) {
theQuestions.innerHTML = "Well Done!";
pageNum.style.display = "none";
}
}
<!DOCTYPE>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<link rel="stylesheet" type="text/css" href="quiz-css.css" />
<link rel="stylesheet" type="text/javascript" href="quiz-css.css" />
</head>
<body onload="">
<div>
<h1 id="quizTitle">My JavaScript Quiz
</h1>
<p id="theQuestions">Click NEXT to start quiz..
</p>
<form id="" action="#" method="post">
<!-- Form Needs Columns -->
<div id="">
<label for="theAnswer"></label>
<input type="text" id="theAnswer" tabindex="1">
</div>
</form>
<span id="pageNum">
</span>
<button onclick="questFunc()">NEXT</button>
</div>
<script src="quiz-js.js"></script>
</body>
</html>

Related

Why doesn't my element update during the else part but during the if part?

I'm making a program where it has a collection of calculators, and for some reason when I try to change the innerhtml of a certain text it only changes it during the if statement and not during the else part.
function Palindrome() {
//Fix not changing to processing when doing new palindrome.
var Division = 0;
var input = document.getElementById("PalindromeInput").value;
var GiveAnswer = document.getElementById("PalindromeAnswer");
var Answer = String(input);
while (0 < 1) {
if (Answer == Answer.split("").reverse().join("")) {
GiveAnswer.innerHTML = `That is a palindrome of the ${Division}th Division.`;
break
} else {
GiveAnswer.innerHTML = `Processing...`;
Division = Division + 1;
Answer = String(parseInt(String(Answer)) + parseInt(Answer.split("").reverse().join("")));
};
};
};
https://replit.com/#ButterDoesFly/Arcane-Calculators#index.html
I'm not sure but I guess the reason for this is that the function never goes to the else part because it gets break every time. Remember that .reverse() reverses the array in place so the if statement will always be true. Try to add different variable for the reversed answer.
function Palindrome() {
//Fix not changing to processing when doing new palindrome.
var Division = 0;
var input = document.getElementById("PalindromeInput").value;
var GiveAnswer = document.getElementById("PalindromeAnswer");
var Answer = String(input);
GiveAnswer.innerHTML = `Processing...`;
setTimeout(()=>{
while (0 < 1) {
if (Answer == Answer.split("").reverse().join("")) {
GiveAnswer.innerHTML = `That is a palindrome of the ${Division}th Division.`;
break
} else {
Division = Division + 1;
Answer = String(parseInt(String(Answer)) + parseInt(Answer.split("").reverse().join("")));
};
};
},1000)
};
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>replit</title>
<link href="style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<p id="PalindromeAnswer">This will tell you the number its at and then the answer.</p>
<input type="text" id="PalindromeInput" placeholder="What number would you like to enter?">
<br>
<input type="button" onclick="Palindrome()" value="Submit" id="PalindromeButton">
<script src="script.js"></script>
<!--
This script places a badge on your repl's full-browser view back to your repl's cover
page. Try various colors for the theme: dark, light, red, orange, yellow, lime, green,
teal, blue, blurple, magenta, pink!
-->
<script src="https://replit.com/public/js/replit-badge.js" theme="blue" defer></script>
</body>
</html>
result is rendering very fast such that changes are not reflecting in ui..add a timeout so that changes reflect in front end

Animating a walk cycle using only Javascript and HTML

I'm working on a project for a friend and he wants a pure walk cycle with only HTML/JS (no CSS). So I've tried to work it out but the image only shows up on the webpage.
It doesn't move when I press any buttons or anything at all.
Please show me where I went wrong. I'm used to using HTML and CSS but this is my first JS so I don't know many terms.
How it appears in the website:
My code (HTML + JS):
<!DOCTYPE html>
<html>
<head>
<title>Javascript Animation</title>
<script language="Javascript">
<!--
var walker = new Array(6);
var curWalker = 0;
var startWalking;
for(var i=0; i<6; i++) {
walker[i] = new Image();
walker[i].src = "walker"+i+".png";
}
function marathon() {
if(curWalker == 5) curWalker == 0;
else ++curWalker;
document.animation.src = walker[curWalker].src;
}
-->
</script>
</head>
<body>
<p><img src="walk1.png" name="animation"> </p>
<form>
<input type="button" name="walk" value="walk" onclick="startWalking=setInterval('marathon(),100);">
<input type="button" name="stop" value="stop" onclick="clearsetInterval(startwalking);">
</form>
</body>
</html>
Here it is how I did it get to work (I had to build my simple images with Paint in order to use them in the animation):
<html>
<head>
<title>Javascript Animation</title>
</head>
<body>
<p><img src="walker1.png" id="animation"> </p>
<form>
<input type="button" name="walk" value="walk" onclick="startWalking=setInterval(marathon,100);">
<input type="button" name="stop" value="stop" onclick="clearInterval(startWalking);">
</form>
<script>
var walker = [];
var curWalker = 0;
var startWalking;
for(var i=0; i<6; i++) {
walker[i] = new Image();
walker[i].src = "walker"+i+".png";
}
function marathon() {
if(curWalker == 5)
curWalker = 0;
else
++curWalker;
document.getElementById("animation").src = walker[curWalker].src;
}
</script>
</body>
</html>
I had to correct several typos/mistakes:
Put the JS just before the </body> closing tag
The first paramether of setInterval() must be a function name, so it must be marathon (you had 'marathon(); note that leading single quote)
In order to get the image to be substituted it is better to access the element though Id instead of name attribute. So I changed the image to <img src="walker1.png" id="animation"> (animation is now the Id) and accessed it through document.getElementById("animation")
Now the animation starts... but stops to the last image instead of restarting to the first.
That was because you used to check the curWalker variable instead of performing an assignment: I put curWalker = 0; instead of curWalker == 0;
Almost there. The loop is complete, but the stop button doesn't work. Two typos are preventing this to work:
clearsetInterval doesn't exist. The function to be called is clearInterval
Javascript is a case sensitive language. You use startwalking variable as a parameter, but the correct variable name is startWalking. So you have to correct the onclick event writing clearInterval(startWalking); instead of clearsetInterval(startwalking);
Your animation is now complete.
Note: as correctly noted by #Mike 'Pomax' Kamermans, nowadays you can avoid the use of onclick as you can attach events to the document (such as "click") by using document.addEventListener.

Load Function to HTML//Generate Random Words

I'm super stuck. I'm creating a hangman game for a class and I cannot get the words to generate and show in my HTML. We're required to have them show as underscores but I cannot get them to show in the HTML either. I've been able to get it to show in the console but not in my HTML.Any help would be appreciated or any assistance in troubleshooting.
please see the code.
//horror movie titles selected to guess
var movieTitles = [
"halloween",
"suspiria",
"audition",
"hereditary",
"the beyond",
"the evil dead",
"the blair witch project"
];
//letters already guessed
var guessedLetters = [];
var numOfLetters = [];
//randomly assigned variable
var movieToGuess = null;
//attempts left
var livesLeft = 8;
//games won
var wins = 0;
//games lost
var losses = 0;
window.onload = function() {
updateMovieToGuess();
};
var updateMovieToGuess = function() {
for (var i = 0; i < numOfLetters.length; i++){
numOfLetters[i] = "_".join(" ");
}
var movieToGuess = movieTitles[Math.floor(Math.random() * movieTitles.length)];
document.getElementById("movie-title").innerHTML = movieToGuess;
};
<!DOCTYPE html>
<html lang="en">
<head>
<title>Hangman</title>
<link rel="stylesheet" type="text/css" href="css/style.css">
<script src="javascript/games.js"></script>
<link href="https://fonts.googleapis.com/css?family=IM+Fell+Double+Pica+SC" rel="stylesheet"> </head>
<body>
<p>Press any key to get started<span id='any-key'> </span> </p>
<p>Movie Title:<span id="movie-title"> </span> </p>
<p>Letters Guessed: <span id='letters'> </span> </p>
<p>Lives Remaining:<span id='lives-left'> </span> </p>
<p>Movies You've Survived:<span id='wins'> </span> </p>
<p>Movies You Died In:<span id='lost'> </span> </p>
<footer> </footer>
</body>
</html>
Two problems:
querySelector is looking for <movie-title> instead of <span id="movie-title">. To fix it, either use getElementById instead of querySelector, or change movie-title to #movie-title.
As Mark Meyer pointed out in a comment, you're using movieToGuess before you set it.
EDIT: I see you edited your question and its code after I answered it. You fixed problem #2 but not #1. Worse, you introduced a new problem: you now add the call to updateMovieToGuess via window.onload inside of updateMovieToGuess instead of at top level, so it never gets called (essentially, you've created a chicken-and-egg problem).

how to make the game save the best score with if statement javascript?

I am building a simple game as practice that counts the number of taps pressed in 3 seconds i have done everything apart from making it able to save the record score and if there is no record score then to show the old record.
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="javascript1.js"></script>
<link type="text/css" rel="stylesheet" href="firstcss.css">
</head>
</head>
<body>
<div id="div1">
<button onclick="myFunction()" id="something">GO
</button>
</div>
<div id="div2">
<p id="paragraph">0</p>
</div>
<p id="don"></p>
<p id="record"></p>
<p id="add"></p>
<script>
var cool = 1;
var red = 0;
function myFunction() {
document.getElementById("something").innerHTML = "Keep Tapping";
document.getElementById("paragraph").innerHTML = cool;
cool++;
var parent = document.getElementById("div1");
setTimeout(function() {
var ooo = cool - 1;
document.getElementById("don").innerHTML = ooo;
var parent = document.getElementById("div1");
var child = document.getElementById("something");
parent.removeChild(child);
var parent1 = document.getElementById("div2");
var child1 = document.getElementById("paragraph");
parent1.removeChild(child1);
if (cool - 1 > red) {
var red = cool - 1;
document.getElementById("record").innerHTML = red;
} else {
document.getElementById("record").innerHTML = red;
document.getElementById("add").innerHTML = red;
}
}, 3000);
}
</script>
</body>
</html>
I am using the if statement at the end but want to know how you would save the high score or if there isnt one to say the old high score. thanks it would be really helpful.
Check out the following resources on local storage:
http://diveintohtml5.info/storage.html
https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Storage
Essentially you can do (taken from the Dive int HTML 5 link):
var foo = localStorage.getItem("bar");
// ...
localStorage.setItem("bar", foo);

JavaScript getElementById returns null

I'm learning JavaScript and I'm wondering why something like:
document.getElementById('partofid'+variable+number) doesn't work?
Here are samples and JSfiddle link, I want "next" button to remove displayed item and show the next one.
HTML:
<div id="div-1"> 1 </div>
<div id="div-2" style="display: none"> 2 </div>
<div id="div-3" style="display: none"> 3 </div>
<div id="div-4" style="display: none"> 4 </div>
<a id="next" href="#">next</a>
JS:
var counter = 1;
var button = document.getElementById('next');
button.addEventListener("click",function(){
var currentDiv = document.getElementById('div-'+counter);
currentDiv.remove();
var nextDiv = document.getElementById('div-'+counter+1);
alert(nextDiv); // why does it return null
alert('div-'+counter+1); // while this doesn't?
nextQuestion.style.display = "block";
counter++;
},true);
Try using parseInt:
var nextDiv = document.getElementById('div-'+parseInt(counter+1,10));
The parseInt function converts its first argument to a string, parses it, and returns an integer.The second arguement is radix which is "base", as in a number system.
Demo
What's going on here is Javascript has some strange rules about types and the + operator.
string + anything means convert anything to string, then concatenate them together. So "foo" + "bar" == "foobar"... and "div" + 1 == "div1".
The the next step, addition is done left to right, so "div" + 1 + 1 goes to "div" + 1 == "div1".
"div1" + 1... remember, convert to string then put together, so we get "div1"+ 1 == "div11".
I would put parenthesis around your arithmetic. "div" + (1+1) would do the right hand side thing first, so (1+1) == 2 as you expect, then "div" + 2 == "div2", so that's what you expect.
As to the alert thing, your first one is looking at the result of the element lookup, and the second one is looking at the string itself. So the first is null because the element lookup didn't find anything.
This code results in string concatenation. E.g. if counter is 1, then you will get div-11
'div-'+counter+1
This is because addition is resolved from right to left.
Then you try to retrieve element with id div-11, but you don't have html element with such an id. That's why the function getElementById returns null.
To solve the problem first add counter to 1 and then join it with div, like this 'div-'+(counter+1)
Because counter+1 = 11 => id = div-11 is not exist. Try this:
var counter = 1;
var button = document.getElementById('next');
button.addEventListener("click",function(){
var currentDiv = document.getElementById('div-'+counter);
currentDiv.remove();
var nextDiv = document.getElementById('div-'+Number(counter+1));
alert(nextDiv); // why does it return null
alert('div-'+Number(counter+1)); // while this doesn't?
nextQuestion.style.display = "block";
counter++;
},true);
it does work and does exactly what you asked it to do but since you do not have a div-11 there is nothing found so the evaluation returns null.
if you want div-2 then simply use order of operations to sum the counter to the number:
Fiddle
Here is your answer:
<html>
<head>
<script>
function load()
{
var counter = 1;
var button = document.getElementById('next');
button.addEventListener("click",function(){
var currentDiv = document.getElementById('div-'+counter);
currentDiv.remove();
var nextDiv = document.getElementById('div-'+(counter+1));
//alert(nextDiv); // why does it return null
//alert('div-'+(counter+1)); // while this doesn't?
nextDiv.style.display = "block";
counter++;
},true);
}
</script>
</head>
<body onload="load()">
<div id="div-1"> 1 </div>
<div id="div-2" style="display: none"> 2 </div>
<div id="div-3" style="display: none"> 3 </div>
<div id="div-4" style="display: none"> 4 </div>
<a id="next" href="#">next</a>
</body>
<html>
To solve this kind of returning "null" values by getElementById("").
you can use script inside the body instead of head it will return the html element.
const m=document.getElementById('one')
const m1=document.getElementById('demo')
console.log(m1);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<p id="demo">sample text</p>
<script src="script.js"></script>
</body>
</html>

Categories