I'm working through How to Learn JavaScript Correctly. About halfway through it has you create a quiz application. I'm able to get it to display the first question, then clicking the next button changes to the second question. But the problem is that when I click the button a third time, the screen clears and the third question never appears.
I'm sure I'm missing something easy. Any idea where I'm going wrong?
app.js:
var allQuestions = [
{question: "Who is Prime Minister of the United Kingdom?",
choices: ["David Cameron", "Gordon Brown", "Winston Churchill", "Tony Blair"],
correctAnswer:0},
{question: "Who is President of the United States?",
choices: ["George Bush", "Barack Obama", "Hilary Clinton"],
correctAnswer:1},
{question: "What is the best state?",
choices: ["Iowa", "Wisconsin", "Colorado", "North Carolina"],
correctAnswer:1}
];
var score = 0;
var i = 0;
$(document).ready(function() {
$('#next').addClass('hidden');
nextQuestion();
});
function nextQuestion() {
var container = $('#container');
var questionName = allQuestions[i].question
var answer = allQuestions[i].correctAnswer;
var choice = 0;
var question = "<div>" + questionName + "</div>";
container.append(question + "<br>");
var choices = allQuestions[i].choices;
for (var j=0;j<choices.length;j++) {
var choice = choices[j];
var radio = "<input type='radio' data-choice='" + j + "' value='" + choice + "' name='" + allQuestions[i].question + "'>" + choices[j];
container.append(radio + "<br>");
}
$('input:radio').on('click',function() {
choice = $(this).data("choice");
$('#next').removeClass('hidden');
});
$('#next').on('click',function() {
$('#next').addClass('hidden');
if (choice === answer) {
alert("Winner!");
}
if (i < allQuestions.length) {
i += 1;
}
container.empty();
nextQuestion();
});
}
Index.html:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Survey</title>
<link rel="stylesheet" href="assets/bootstrap.min.css">
<link rel="stylesheet" href="assets/bootstrap.responsive.min.css">
<link rel="stylesheet" href="assets/base.css">
</head>
<body>
<!-- index.html -->
<div id="container">
<script src="js/lib/jquery.min.js"></script>
<script src="js/lib/underscore-min.js"></script>
<script src="js/lib/bootstrap.min.js"></script>
<script src="js/app.js"></script>
</div>
<input type='submit' value='Next' id='next'>
</body>
</html>
Remove the following code from withing the function; you're binding the events multiple times. At some time when you click #next once it may advance multiple time as it responds to the multiple binds.
$('input:radio').on('click',function() {
choice = $(this).data("choice");
$('#next').removeClass('hidden');
});
$('#next').on('click',function() {
$('#next').addClass('hidden');
if (choice === answer) {
alert("Winner!");
}
if (i < allQuestions.length) {
i += 1;
}
container.empty();
nextQuestion();
});
Put the code inside a DOM ready event with the modification shown:
$(function() {
$(document).on('change', 'input:radio', function() {
choice = $(this).data("choice");
$('#next').removeClass('hidden');
});
$('#next').on('click',function() {
$('#next').addClass('hidden');
if (choice === answer) {
alert("Winner!");
}
if (i < allQuestions.length) {
i += 1;
}
container.empty();
nextQuestion();
});
});
Related
After my last question, I tried to use the JS file and it wouldn't work alongside clicking an HTML button to begin the functions in the JS file; After the JS script asks for money and the code for a soda product, I couldn't restart the function again from clicking "BEGIN" in my HTML page.
How do I solve this?
*I would like to challenge myself to script Javascript functions without using the function in HTML.
*I am using AUD denominations since I live in Australia.
var beginMachine = document.getElementById("beginMachine");
beginMachine.addEventListener("click", vendingFunction);
function vendingFunction() {
var $money = 0;
var codeSequence = ["A1", "A2", "B1", "B2"];
var $soda = ["Coca-Cola", "Fanta", "Sprite", "Schweppes"];
const coinValue = {'0.20': 0.20, '0.50': 0.50, '1.00': 1.00, '2.00': 2.00};
const sodaPrice = [1.55, 2.95, 1.85, 3.90];
const formatMoney = new Intl.NumberFormat('en-AU', {style: 'currency', currency: 'AUD'}).format; //Change the currency format to AUD for clarity in currency used.
return {
insertCoin: () => { //The arrow function '=>' acts a simple indicator to call a function
var coin = window.prompt("Insert any coin. (20c, 50c, $1, $2)");
$money += coinValue[coin] || 0;
if (typeof coinValue[coin] === 'undefined') alert('Invalid Choice'); //'undefined' means no value or invalid value
console.log('You now have ' + formatMoney($money));
},
selectItem: () => {
var sodaChoice = window.prompt("Select your code.");
console.log(sodaChoice);
if (sodaChoice == "A1") {
window.alert("You selected Coca-Cola.");
window.alert("This costs $" + sodaPrice[0] + "."); //sodaprice[0] calls the first element in "sodaPrice's" array
window.alert(sodaPrice[0] <= $money ? "You have enough." : "You don't have enough.");
}
if (sodaChoice == "A2") {
window.alert("You selected Fanta.");
window.alert("This costs $" + sodaPrice[1] + ".");
window.alert(sodaPrice[1] <= $money ? "You have enough." : "You don't have enough.");
}
if (sodaChoice == "B1") {
window.alert("You selected Sprite.");
window.alert("This costs $" + sodaPrice[2] + ".");
window.alert(sodaPrice[2] <= $money ? "You have enough." : "You don't have enough.");
}
if (sodaChoice == "B2") {
window.alert("You selected Schweppes");
window.alert("This costs $" + sodaPrice[3] + ".");
window.alert(sodaPrice[3] <= $money ? "You have enough." : "You don't have enough.");
}
}
}
}
const app = vendingFunction();
for (let i = 0; i < 5; i++) {
app.insertCoin();
}
app.selectItem();
//Code from dave in StackOverflow <https://stackoverflow.com/questions/67929579/how-do-you-program-this-javascript-file-for-allowing-more-than-one-denominations/67929809
//See <https://www.youtube.com/watch?v=qsEtXR38IQ8&ab_channel=EnvatoTuts%2B>
body {background-color: lightgrey;}
.vendingMachine
{
position:static;
top: 0;
left: 0;
z-index: 1;
}
.mainFont
{
font-family: Arial, sans-serif;
font: 12px/14px;
}
<!DOCTYPE html>
<html> <!-- Tells this document is coded in HTML5 -->
<head>
<link rel="stylesheet" href="0az_style.css"><!-- Links to the CSS file that handles the layout and design of the webiste, specifically the buttons' and vending machine's positions. -->
<title>Vending Machine</title> <!-- Names the browser tab -->
</head>
<!--Calls the mainFont variable in the CSS file to change every letter into Arial-->
<body class="mainFont"><!--Changes every letter to a specific font-->
<!--Creates a large heading like Heading 1 in Word-->
<h1>Welcome to the Vending Machine</h1>
<!--<div> generically stores CSS code but for these lines, Javascript is called upon to activate the remaining scripts-->
<div>
<img class="fit-picture"
src="Vending-Machine-alt.png"
width="1255"
height="1835"
alt="Picture of a vending machine.">
</div>
<br>
<!-- From https://stackoverflow.com/questions/9530954/how-to-call-external-javascript-function-in-html -->
<!-- Adding <script type="text/javascript"></script> calls this function right away. Perhaps use inline JS to tell the button to load JS script after the page loads.-->
<button id="beginMachine">BEGIN</button>
<br>
<!--<a href= '0az_how_to_use.html'> links to the manual page in this project's main folder-->
<h2><a href= '0az_how_to_use.html'>How to use the vending machine</a></h2>
</body>
</html>
Your vendingFunction() function returns an object with functions, it doesn't execute them. You need another function that would execute them:
var beginMachine = document.getElementById("beginMachine");
beginMachine.addEventListener("click", start);
function vendingFunction() {
var $money = 0;
var codeSequence = ["A1", "A2", "B1", "B2"];
var $soda = ["Coca-Cola", "Fanta", "Sprite", "Schweppes"];
const coinValue = {'0.20': 0.20, '0.50': 0.50, '1.00': 1.00, '2.00': 2.00};
const sodaPrice = [1.55, 2.95, 1.85, 3.90];
const formatMoney = new Intl.NumberFormat('en-AU', {style: 'currency', currency: 'AUD'}).format; //Change the currency format to AUD for clarity in currency used.
return {
insertCoin: () => { //The arrow function '=>' acts a simple indicator to call a function
var coin = window.prompt("Insert any coin. (20c, 50c, $1, $2)");
$money += coinValue[coin] || 0;
if (typeof coinValue[coin] === 'undefined') alert('Invalid Choice'); //'undefined' means no value or invalid value
console.log('You now have ' + formatMoney($money));
},
selectItem: () => {
var sodaChoice = window.prompt("Select your code.");
console.log(sodaChoice);
if (sodaChoice == "A1") {
window.alert("You selected Coca-Cola.");
window.alert("This costs $" + sodaPrice[0] + "."); //sodaprice[0] calls the first element in "sodaPrice's" array
window.alert(sodaPrice[0] <= $money ? "You have enough." : "You don't have enough.");
}
if (sodaChoice == "A2") {
window.alert("You selected Fanta.");
window.alert("This costs $" + sodaPrice[1] + ".");
window.alert(sodaPrice[1] <= $money ? "You have enough." : "You don't have enough.");
}
if (sodaChoice == "B1") {
window.alert("You selected Sprite.");
window.alert("This costs $" + sodaPrice[2] + ".");
window.alert(sodaPrice[2] <= $money ? "You have enough." : "You don't have enough.");
}
if (sodaChoice == "B2") {
window.alert("You selected Schweppes");
window.alert("This costs $" + sodaPrice[3] + ".");
window.alert(sodaPrice[3] <= $money ? "You have enough." : "You don't have enough.");
}
}
}
}
function start()
{
const app = vendingFunction();
for (let i = 0; i < 5; i++) {
app.insertCoin();
}
app.selectItem();
}
start();
//Code from dave in StackOverflow <https://stackoverflow.com/questions/67929579/how-do-you-program-this-javascript-file-for-allowing-more-than-one-denominations/67929809
//See <https://www.youtube.com/watch?v=qsEtXR38IQ8&ab_channel=EnvatoTuts%2B>
body {background-color: lightgrey;}
.vendingMachine
{
position:static;
top: 0;
left: 0;
z-index: 1;
}
.mainFont
{
font-family: Arial, sans-serif;
font: 12px/14px;
}
<!DOCTYPE html>
<html> <!-- Tells this document is coded in HTML5 -->
<head>
<link rel="stylesheet" href="0az_style.css"><!-- Links to the CSS file that handles the layout and design of the webiste, specifically the buttons' and vending machine's positions. -->
<title>Vending Machine</title> <!-- Names the browser tab -->
</head>
<!--Calls the mainFont variable in the CSS file to change every letter into Arial-->
<body class="mainFont"><!--Changes every letter to a specific font-->
<!--Creates a large heading like Heading 1 in Word-->
<h1>Welcome to the Vending Machine</h1>
<!--<div> generically stores CSS code but for these lines, Javascript is called upon to activate the remaining scripts-->
<div>
<img class="fit-picture"
src="Vending-Machine-alt.png"
width="1255"
height="1835"
alt="Picture of a vending machine.">
</div>
<br>
<!-- From https://stackoverflow.com/questions/9530954/how-to-call-external-javascript-function-in-html -->
<!-- Adding <script type="text/javascript"></script> calls this function right away. Perhaps use inline JS to tell the button to load JS script after the page loads.-->
<button id="beginMachine">BEGIN</button>
<br>
<!--<a href= '0az_how_to_use.html'> links to the manual page in this project's main folder-->
<h2><a href= '0az_how_to_use.html'>How to use the vending machine</a></h2>
</body>
</html>
I am going through this JavaScript tutorial and ran into an issue that I hope someone can assist me with. After selecting the last question on the quiz, my showScore() function displays the results as "undefined". Through some further debugging, I found that it was a problem with my quiz object. In my PopulateQuestion() function, I am able to print out the quiz object before executing the showScore() function. However, when I attempt to print out the quiz object from within the showScore() function, it returns undefined.
I would like to work on my ability to debug issues that come up like this. Based on debugging that I have done so far, my educated guess is that this is a scope issue, but I am stuck. Does anyone have any suggestions for debugging this further?
Here is my code
Index.html
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>JS Quiz</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="main.css">
</head>
<body>
<div class="quiz-container">
<div id="quiz">
<h1>Star Wars Quiz</h1>
<hr style="margin-top: 20px;" />
<p id="question">Who is Darth Vader?</p>
<div class="buttons">
<button id="b0"><span id="c0"></span></button>
<button id="b1"><span id="c1"></span></button>
<button id="b2"><span id="c2"></span></button>
<button id="b3"><span id="c3"></span></button>
</div>
<hr style="margin-top: 50px" />
<footer>
<p id="progress">Question x of n</p>
</footer>
</div>
</div>
<script src="quiz-controller.js"></script>
<script src="question.js"></script>
<script src="app.js"></script>
</body>
</html>
app.js
function populateQuestion() {
if(quiz.isEnded()) {
// display score
console.log(quiz);
showScore();
} else {
// display question
var qElement = document.getElementById('question');
qElement.innerHTML = quiz.getCurrentQuestion().text;
// display choices
var choices = quiz.getCurrentQuestion().choices;
for(var i = 0; i < choices.length; i++) {
var choice = document.getElementById('c' + i);
choice.innerHTML = choices[i];
guess("b" + i, choices[i]);
}
showProgress();
}
}
function guess(id, guess) {
var button = document.getElementById(id);
button.onclick = function() {
quiz.guess(guess);
populateQuestion();
};
}
function showProgress() {
var currentQuestionNum = quiz.questionIndex + 1;
var progress = document.getElementById("progress");
progress.innerHTML = "Question " + currentQuestionNum + " of " + quiz.questions.length;
}
function showScore() {
console.log(quiz);
var resultsHTML = "<h1>Results</h1>";
resultsHTML += "<h2 id='score'>Your Score: " + quiz.getScore() + "</h2>";
var quiz = document.getElementById("quiz");
quiz.innerHTML = resultsHTML;
}
var questions = [
new Question("Who is Darth Vader?",
["Luke Skywalker", "Anakin Skywalker", "Your Mom", "Your Dad"],
"Anakin Skywalker"),
new Question("What is the name of the third episode?",
["Return of the Jedi", "Revenge of the Sith", "A New Hope", "The Empire Strikes Back"],
"Revenge of the Sith"),
new Question("Who is Anakin Skywalker's son?",
["Luke Skywalker", "Anakin Skywalker", "Your Mom", "Your Dad"],
"Luke Skywalker"),
new Question("What is the name of the sixth episode?",
["Return of the Jedi", "Revenge of the Sith", "A New Hope", "The Empire Strikes Back"],
"Return of the Jedi")
];
var quiz = new Quiz(questions);
populateQuestion();
question.js
function Question(text, choices, answer) {
this.text = text;
this.choices = choices;
this.answer = answer;
}
Question.prototype.correctAnswer = function(choice) {
return choice === this.answer;
};
quiz-controller.js
function Quiz(questions) {
this.score = 0;
this.questionIndex = 0;
this.questions = questions;
}
Quiz.prototype.getScore = function() {
return this.score;
};
Quiz.prototype.getCurrentQuestion = function() {
return this.questions[this.questionIndex];
};
Quiz.prototype.isEnded = function() {
return this.questionIndex === this.questions.length;
};
Quiz.prototype.guess = function(answer) {
if(this.getCurrentQuestion().correctAnswer(answer)) {
this.score++;
}
this.questionIndex++;
};
Your problem is that in the showScore() function you define a local variable with the name quiz. This local variable hides the global variable with the same name (even though it is defined later in the code).
You can easily fix that by renaming your local variable in showScore (below shown as q instead of quiz):
function populateQuestion() {
if(quiz.isEnded()) {
// display score
console.log(quiz);
showScore();
} else {
// display question
var qElement = document.getElementById('question');
qElement.innerHTML = quiz.getCurrentQuestion().text;
// display choices
var choices = quiz.getCurrentQuestion().choices;
for(var i = 0; i < choices.length; i++) {
var choice = document.getElementById('c' + i);
choice.innerHTML = choices[i];
guess("b" + i, choices[i]);
}
showProgress();
}
}
function guess(id, guess) {
var button = document.getElementById(id);
button.onclick = function() {
quiz.guess(guess);
populateQuestion();
};
}
function showProgress() {
var currentQuestionNum = quiz.questionIndex + 1;
var progress = document.getElementById("progress");
progress.innerHTML = "Question " + currentQuestionNum + " of " + quiz.questions.length;
}
function showScore() {
console.log(quiz);
var resultsHTML = "<h1>Results</h1>";
resultsHTML += "<h2 id='score'>Your Score: " + quiz.getScore() + "</h2>";
var q = document.getElementById("quiz");
q.innerHTML = resultsHTML;
}
var questions = [
new Question("Who is Darth Vader?",
["Luke Skywalker", "Anakin Skywalker", "Your Mom", "Your Dad"],
"Anakin Skywalker"),
new Question("What is the name of the third episode?",
["Return of the Jedi", "Revenge of the Sith", "A New Hope", "The Empire Strikes Back"],
"Revenge of the Sith"),
new Question("Who is Anakin Skywalker's son?",
["Luke Skywalker", "Anakin Skywalker", "Your Mom", "Your Dad"],
"Luke Skywalker"),
new Question("What is the name of the sixth episode?",
["Return of the Jedi", "Revenge of the Sith", "A New Hope", "The Empire Strikes Back"],
"Return of the Jedi")
];
function Question(text, choices, answer) {
this.text = text;
this.choices = choices;
this.answer = answer;
}
Question.prototype.correctAnswer = function(choice) {
return choice === this.answer;
};
function Quiz(questions) {
this.score = 0;
this.questionIndex = 0;
this.questions = questions;
}
Quiz.prototype.getScore = function() {
return this.score;
};
Quiz.prototype.getCurrentQuestion = function() {
return this.questions[this.questionIndex];
};
Quiz.prototype.isEnded = function() {
return this.questionIndex === this.questions.length;
};
Quiz.prototype.guess = function(answer) {
if(this.getCurrentQuestion().correctAnswer(answer)) {
this.score++;
}
this.questionIndex++;
};
var quiz = new Quiz(questions);
populateQuestion();
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>JS Quiz</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="main.css">
</head>
<body>
<div class="quiz-container">
<div id="quiz">
<h1>Star Wars Quiz</h1>
<hr style="margin-top: 20px;" />
<p id="question">Who is Darth Vader?</p>
<div class="buttons">
<button id="b0"><span id="c0"></span></button>
<button id="b1"><span id="c1"></span></button>
<button id="b2"><span id="c2"></span></button>
<button id="b3"><span id="c3"></span></button>
</div>
<hr style="margin-top: 50px" />
<footer>
<p id="progress">Question x of n</p>
</footer>
</div>
</div>
<script src="quiz-controller.js"></script>
<script src="question.js"></script>
<script src="app.js"></script>
</body>
</html>
There is private variable quiz in showScore
function which is getting hoisted to the top of the
function as follows:
Your code:
function showScore() {
console.log(quiz);
var resultsHTML = "<h1>Results</h1>";
resultsHTML += "<h2 id='score'>Your Score: " + quiz.getScore() + "</h2>";
var quiz = document.getElementById("quiz");
What internally happens:
function showScore() {
var quiz = undefined; // hoisting is happening here. So quiz is not reffering to public quiz variable anymore.
console.log(quiz);
var resultsHTML = "<h1>Results</h1>";
resultsHTML += "<h2 id='score'>Your Score: " + quiz.getScore() + "</h2>";
var quiz = document.getElementById("quiz");
I am new to the programming world and have been working on a trivia-game style project. The problem I am encountering is as follows: "Uncaught ReferenceError: answer is not defined at HTMLButtonElement.button.onclick".
My question is as follows: How are my question answers not being stored when pressing an answer and what is a better way to define answer in my code? Any help would greatly be appreciated.
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Trivia Game</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/css/bootstrap.min.css" />
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"
crossorigin="anonymous"></script>
<link href="https://fonts.googleapis.com/css?family=Lora" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="assets/css/style.css" />
</head>
<body>
<div class="grid">
<div id="trivia">
<h1>A Golfer's Trivia</h1>
<!-- for question -->
<div id="questionName">
<p id="question"></p>
</div>
<p id="progress"></p>
<!-- options for the questions -->
<div class="buttons">
<button id="btn0"><span id="option0"></span></button>
<button id="btn1"><span id="option1"></span></button>
<button id="btn2"><span id="option2"></span></button>
<button id="btn3"><span id="option3"></span></button>
</div>
<div>
<p id="timer"></p>
<p id="show-clock"></p>
</div>
</div>
</div>
<script type="text/javascript" src="assets/javascript/game.js"></script>
</body>
</html>``
JAVASCRIPT
// Keeping score
var unanswered = 0;
var questionIndex = 0;
var score = 0;
var questions = 0;
var answer;
function Quiz(questions) {
this.score = 0;
this.questions = questions;
this.questionIndex = 0;
}
function getQuestionIndex() {
return this.questions[this.questionIndex];
}
function endGame() {
return this.questions.length === this.questionIndex;
}
function guess(answer) {
if (this.getQuestionIndex() === correctAnswer(answer)) {
this.score++;
}
this.questionIndex++;
}
// functions for questions
function Question(text, choices, answer) {
this.text = text;
this.choices = choices;
this.answer = answer;
}
// check user answer
function correctAnswer(choice) {
return choice === this.answer;
}
// have questions appear if game is still going
function populate() {
console.log("populating");
if (endGame()) {
showScores();
}
else {
var element = document.getElementById("question");
element.innerHTML = getQuestionIndex().text;
// have options appear for each question
var choices = getQuestionIndex().choices;
for (var i = 0; i < choices.length; i++) {
var element = document.getElementById("option" + i);
element.innerHTML = choices[i];
guess("btn" + i, choices[i]);
}
showProgress()
}
}
// store user guess
function guess(id) {
var button = document.getElementById(id);
button.onclick = function () {
questionIndex++;
populate();
guess(answer);
}
}
// show which question player is on
function showProgress() {
var currentQuestionNumber = questionIndex + 1;
var element = document.getElementById("progress");
element.innerHTML = "Question " + currentQuestionNumber + " of " + questions.length;
}
// display scores at end of game
function showScores() {
var gameOver = "<h1>Results</h1>" + "<h2 class='corr score'> Correct Answers: " + score + "<h2>" + "<br>" + "<h2 class = 'wrong score'>Wrong Answers: " + (questions.length - score) + "<h2 class = 'unanswered score'>Unanswered: " + "<h2>";
var results = document.getElementById("trivia");
results.innerHTML = gameOver;
}
// sets of questions, options, answers
var questions = [
new Question("Where was the game of golf originally founded?",
["Scotland", "China", "England", "United States"],
"Scotland"),
new Question("Who is the only female golfer to make a cut at a PGA Tour event?",
["Michelle Wie", "Annika Sorensteim", "Lexi Thompson", "Babe Zaharias"],
"Babe Zaharias"),
new Question("What is the name for a hole-in-one on a par five?",
["Triple Eagle", "Double Ace", "Condor", "Albatross"],
"Condor"),
new Question("Who holds the record for the most PGA Tour victories?",
["Tiger Woods", "Jack Nicklaus", "Ben Hogan", "Sam Snead"],
"Sam Snead"),
new Question("What percentage of golfers will never achieve a handicap of 18 or less?",
["50 percent", "73 percent", "80 percent", "91 percent"],
"80 percent"),
new Question("How many dimples are on a standard regulation golf ball?",
["336", "402", "196", "468"],
"336"),
new Question("Who was considered the first professional golfer in history?",
["Bobby Jones", "Byron Nelson", "Walter Hagen", "Old Tom Morris"],
"Walter Hagen"),
new Question("Who is the youngest player to win the Masters?",
["Tiger Woods", "Jack Nicklaus", "Jordan Speith", "Arnold Palmer"],
"Tiger Woods")
];
populate();
var intervalId;
$("#btn").on("click", run);
// The run function sets an interval
function run() {
clearInterval(intervalId);
}
var timeLeft = 10;
var displayClock = document.getElementById('timer');
var timerId = setInterval(countdown, 1000);
function countdown() {
if (timeLeft === 0) {
unanswered++;
questionIndex++;
populate();
alert("You did not answer in time!");
timeLeft = 10;
// reset timer, pull question
run();
} else {
displayClock.innerHTML = timeLeft + ' seconds remaining';
timeLeft--;
}
}
run();
I guess you're facing another problem here. Here are 2 functions taken off your script:
guess(any) version 1
function guess(answer) {
if (this.getQuestionIndex() === correctAnswer(answer)) {
this.score++;
}
this.questionIndex++;
}
guess(any)version 2
function guess(id) {
var button = document.getElementById(id);
button.onclick = function () {
questionIndex++;
populate();
guess(answer);
}
}
You have 2 of a function named guess(). Although the names of both values vary, from Javascript's standpoint they both look like this:
function guess(value){}
How is JS supposed to know which of them you intend to call?
Rename at least one of them in order to having total unambiguousness among your function names. And try again.
Ive been trying to learn Javascript OOP so i made a quiz. However for some reason my html is not being populated with the questions and answers I made. I cannot figure out the problem. Any help would be greatly appreciated!
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Edgy Quiz</title>
<link type="text/css" rel="stylesheet" href="style.css"/>
</head>
<body>
<h1>In a world where everyone is looking to stand out from the crowd</h1>
<h2>Does the extend of your own edginess confuse you?</h2>
<h3>Well this scientifically proven personality test was built for you!</h3>
<div class="grid">
<div id="quiz">
<h4>How edgy are you?</h4>
<hr style="margin-top: 20px">
<p id="question"></p>
<div class="buttons">
<button id="btn0"><span id="choice0"></span></button>
<button id="btn1"><span id="choice1"></span></button>
<button id="btn2"><span id="choice2"></span></button>
<button id="btn3"><span id="choice3"></span></button>
</div>
<hr style="margin-top: 50px">
<footer>
<p id="progress">Question x of y.</p>
</footer>
</div>
</div>
<script type="text/javascript" src="script.js"></script>
</body>
</html>
$(window).load(function() {
function Question(text, choices, answer) {
this.text = text;
this.choices = choices;
this.answer = answer;
}
Question.prototype.correctAnswer = function(choice) {
return choice === this.answer;
}
function Quiz(questions) {
this.score = 0;
this.questions = questions;
this.questionIndex = 0;
}
Quiz.prototype.getQuestionIndex = function() {
return this.questions[this.questionIndex];
}
Quiz.prototype.isEnded = function() {
return this.questions.length === this.questionIndex;
}
Quiz.prototype.guess = function(answer) {
if (this.getQuestionIndex().correctAnswer(answer)) {
this.score++;
}
this.questionIndex++;
}
function populate() {
if(quiz.isEnded()) {
showScores();
}
else {
var element = document.getElementById("question");
element.innerHTML = quiz.getQuestionIndex().text;
var choices = quiz.getQuestionIndex().choices;
for(var i = 0; i < choices.length; i++) {
var element = document.getElementById("choice" + i);
element.innerHTML = choices[i];
guess("btn" + i, choices[i]);
}
showProgress();
}
}
function guess(id, guess) {
var button = document.getElementById(id);
button.onclick = function () {
quiz.guess(guess);
populate();
}
}
function showProgress () {
var currentQuestionNumber = quiz.questionIndex + 1;
var element = document.getElementById("progress");
element.innerHTML = "Question " + currentQuestionNumber + "of " +
quiz.questions.length;
}
function showScores() {
var gameOverHtml = "<h1>Result</h1>";
gameOverHtml += "<h2 id='score'>Your score: ' + quiz.score + '</h2>";
var element = document.getElementById("quiz");
element.innerHTML = gameOverHtml;
}
var questions = [
new Question ("How have you discovered this test?", ["I was bored browsing
online", "I want to see how edgy I am", "Im a friend doing it out of
Sympathy", "Im looking at this weirdo's portfolio"], "Im looking at this
weirdo's portfolio"),
new Question ("How edgy do you think you are?", ["Extremely edgy", "Im very
mainstream", "What does edgy even mean?", "I don't do labels"], "I don't do
labels"),
new Question ("Of these colors which is your favourite?", ["Blue", "Orange",
"Majenta", "Black"], ""),
new Question ("Could you bring yourself to hurt a living thing?", ["Only if
it hurt me first", "I hurt stuff for fun", "No never how could you im a
vegan", "I hurt myself all the time"], "I hurt myself all the time"),
new Question ("If someone tickled you how would you respond?", ["Tickle
fight", "Run away", "Punch them in the face", "Write a song"], "Write a
song"),
];
var quiz = new Quiz(questions);
populate();
});
In firebug console 10 paragraphs is displayed in the source code of the page, but only the first one contains text.
It looks like the loop inserted the text each time into the same paragraph, overwriting it's value. How to insert the text into each paragraph?
(function(){
var names = ["Yaakov", "John", "Jen", "Jason", "Paul",
"Frank", "Larry", "Paula", "Laura", "Jim"];
for (var name in names) {
var new_par = document.createElement("p");
new_par.id = "new_par";
var greeter = document.getElementById("greeter");
greeter.appendChild(new_par);
var firstChar = names[name].charAt(0).toLowerCase();
if (firstChar === 'j') {
//byeSpeaker.speak(names[name]);
document.getElementById("new_par").innerHTML = "Goodbye" + " " + names[name];
} else {
//helloSpeaker.speak(names[name]);
document.getElementById("new_par").innerHTML = "Hello" + " " + names[name];
}
}
})();
Here's the HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Module 4 Solution Starter</title>
</head>
<body>
<h1>Module 4 Solution Starter</h1>
<div id="greeter"></div>
<script src="SpeakHello.js"></script>
<script src="SpeakGoodBye.js"></script>
<script src="script.js"></script>
</body>
</html>
The problem is that you are creating ten nodes with the same id, new_par, so you are always getting a reference to the first #new_par when you do
document.getElementById("new_par").innerHTML
The simplest solution will be to use the reference you already have, no need to call getElementById.
new_par.innerHTML = ...
The problem is that each paragraph has the same id. I added a counter variable, to add at the end of id...
(function(){
var counter = 0;
var names = ["Yaakov", "John", "Jen", "Jason", "Paul",
"Frank", "Larry", "Paula", "Laura", "Jim"];
for (var name in names) {
var new_par = document.createElement("p");
var par_id = "new_par" + counter;
new_par.id = par_id;
var greeter = document.getElementById("greeter");
greeter.appendChild(new_par);
var firstChar = names[name].charAt(0).toLowerCase();
if (firstChar === 'j') {
//byeSpeaker.speak(names[name]);
document.getElementById(par_id).innerHTML = "Goodbye" + " " + names[name];
} else {
//helloSpeaker.speak(names[name]);
document.getElementById(par_id).innerHTML = "Hello" + " " + names[name];
}
counter++;
}
})();