I'm trying to make a simple javascript quiz, but its been difficult figuring out the scoring. I'm a beginner with javascript so bear with me. I'm creating a quiz that has a new question on a new page and the last page displays the score. Currently when I answer a question and go to the next page and the score resets. It's probably the variable I'm using but I don't know enough about javascript to fix it.
I have four buttons, one correct answer and three incorrect answers. The correct answer triggers and function that adds 1 to the variable x which is the score. The variable x is a global variable. So when I go to the next page to see the score the score resets at 0.
I'm trying to find a simple solution to this issue if possible. I condensed the code to one page for this post but the score is suppose to print the next page not the question page. Thank you to all who reads this!
var x = 0;
function myFunctionCorrect() {
x = x + 1;
document.getElementById("demo").innerHTML = "Correct!";
document.getElementById("scoretext").innerHTML = "Your score is " + x + ".";
}
function myFunctionWrong() {
document.getElementById("demo").innerHTML = "Wrong!";
}
<button onclick="myFunctionCorrect()" class="elementbutton">Spandrel</button>
<button onclick="myFunctionWrong()" class="elementbutton">Attic</button>
<button onclick="myFunctionWrong()" class="elementbutton">Roundrel</button>
<button onclick="myFunctionWrong()" class="elementbutton">Plinth</button>
<p id="demo"></p>
<p id="scoretext"></p>
var x = 0;
function myFunctionCorrect() {
x = x + 1;
localStorage.setItem("score", x);
}
function showScore() {
var score=localStorage.getItem("score")
document.getElementById("scoretext").innerHTML = "Your score is " + score + ".";
}
You have to do something like this your myFunctionCorrect should store the value in local-storage and then a function like showScore can retrieve the score from localstorage and show to user.
I don't see where your are moving to the next page, but javascript variables don't typically carry over from page to page, unless you were using frames or something and storing your JS in a parent frame.
Off the top of my head, I would persist the variables in the url, then parse then on the next screen.
If you were using a server-side language, I do it in a form instead.
I agree with everyone here on persisting the variables in the URL. I know you mentioned you're a beginner--even variables with global scope don't persist across different pages, so you can pass the score into the URL when the score updates, perhaps through the URL's hash:
function myFunctionCorrect() {
x = x + 1;
document.getElementById("demo").innerHTML = "Correct!";
document.getElementById("scoretext").innerHTML = "Your score is " + x + ".";
let scoreHash = `score:${x}`
window.location.hash = "scoreHash"
}
Then, when a new page loads, you can grab the hash from the referrer URL and re-declare it as your global x variable. So include this function at the top of your Javascript for each page:
var x;
document.onload = function() {
let previousScore = document.referrer;
x = previousScore
}
Related
I am trying to create a Countup counter Starting from 1 to 10000 and i do not want it to reset when user refreshes the page or cancels the page. The Counter should start from 1 for every user that visits the page and keep running in background till it gets to 10000 even if the page is closed.
I have written the page below which;
Starts from the specified number for every new visitor
Saves the progress and does not reset when page is refreshed, however
It does not keep counting when page is closed and starts from the last progress when user closes the tab and comes back later. My code is
function countUp() {
var countEl = document.querySelector('.counter');
var countBar = document.querySelector('.progress-bar');
var x = parseInt(localStorage.getItem('lastCount')) - 1 || 1;
var y = countEl.dataset.to;
var z = countBar.dataset.to;
function addNum() {
countEl.innerHTML = x;
x += 1;
if (x > y && x > z) {
clearInterval(timer);
}
localStorage.setItem('lastCount', x);
}
var timer = window.setInterval(addNum, 1000);
localStorage.setItem("addNum", counter);
toggleBtn.addEventListener('click', function(){
countUp();
toggleBtn.classList.add('hidden');
});
}
countUp();</script>
<body onload=countUp();>
<div class="counter" data-from="0" data-to="10000000"></div>
<div class="progress-bar" data-from="0" data-to="10000000"></div>
</body>
It's difficult to show an example on StackOverflow because it doesn't let you fiddle with localStorage but, it sounds like you want something like:
When a user visits the page check localStorage for a timestamp.
If timestamp exists, go to step 4
Timestamp doesn't exist so get the current timestamp and stash it in localStorage.
Get the current timestamp. Subtract the timestamp from before. If over 10,000, stop, you're done.
Display difference calculated in step 4.
Start a 1 second timer, when time is up, go to step 4.
Something along those lines should work even if they refresh the page and since you are calculating from the original timestamp it will "count" in the background even if the page is closed.
window.addEventListener("DOMContentLoaded", () => {
const start = localStorage.getItem("timestamp") || Date.now();
localStorage.setItem("timestamp", start);
function tick() {
const now = Date.now();
const seconds = Math.floor((now - start) / 1000);
const display = document.getElementById("display");
if (seconds > 10000) return display.innerHTML = "We're done";
display.innerHTML = seconds;
setTimeout(tick, 1000);
}
tick();
});
<div id="display"></div>
So, client-side code can't normally execute when a client-side javascript page is closed.
What you could do, however, is calculate where the timer should be then next time it is loaded.
For example, in your addNum() function, you could in addition to the last count, also store the current date (and time).
function addNum() {
countEl.innerHTML = x;
x += 1;
if (x > y && x > z) {
clearInterval(timer);
}
localStorage.setItem('lastCount', x);
localStorage.setItem('lastDate', new Date());
}
Then, when your code starts, you can retrieve lastDate, and then subtract the current Date() from it.
Then use that to add the difference to your counter.
function countUp() {
let storedCount = parseInt(localStorage.getItem('lastCount'));
let storedDate = Date.parse(localStorage.getItem('lastDate'));
let now = new Date()
let diffSeconds = (now.getTime() - storedDate.getTime()) / 1000;
let storedCount += diffSeconds;
var countEl = document.querySelector('.counter');
var countBar = document.querySelector('.progress-bar');
var x = storedCount - 1 || 1;
var y = countEl.dataset.to;
var z = countBar.dataset.to;
}
I'm sure there are some more changes required to make it work with your code, but the idea is to store the current time so that when the page is closed and reopened, you can 'adjust' the count to catch up to what it should be.
What you want here is not possible just from the client-side code, there is no way for 2 different machines to share that information at all.
Here's the thing though, you can do this with a backend where the database gets updated every time a new IP hits the server. Note with this approach, a user here is one system and not different browsers or sessions.
To update this real-time for someone who is already on the website, run a timer and call an API that specifically gives you the count. Therefore the page gets updated frequently. You can also do this with react-query as it comes with inbuilt functions to do all this.
I have tried for so long to get this code to work. I'm programming a little game when you need to be fast, so I made a stopwatch. But the stopwatch just doesn't want to work. Instead of the seconds the stopwatch is showing Object Undefined and I don't know why. This is the code i'm using:
var stopwatchFrame = 0;
var stopwatchSeconds = 0;
var stopwatchSecondsString = "Nothing";
stopwatchFrame+=1;
stopwatchSeconds = floor(stopwatchFrame/updatesPerSecond);
stopwatchSecondsString = toString(stopwatchSeconds);
var = "Total time: " + stopwatchSecondsString + " seconds";
I'm using a simple website called Koda.nu, it's a Swedish website for young to learn programming in JS. Some functions is coming from their built in source. I'm new to programming so that's why.
You are missing a variable name where you have a value of "Total time: " + stopwatchSecondsString + " seconds"; It should be:
var totalTime = "Total time: " + stopwatchSecondsString + " seconds";
Also read what #Jaromanda X wrote in the comments section. It should be like this:
stopwatchSeconds = Math.floor(stopwatchFrame/updatesPerSecond);
stopwatchSecondsString = stopwatchSeconds.toString();
We don't have an access to your updatesPerSecond variable so that would throw an error as well. If declared, your code would work like this:
var stopwatchFrame = 0;
var stopwatchSeconds = 0;
var stopwatchSecondsString = "Nothing";
var updatesPerSecond = 0;
stopwatchFrame += 1;
stopwatchSeconds = Math.floor(stopwatchFrame / updatesPerSecond);
stopwatchSecondsString = stopwatchSeconds.toString();
var totalTime = "Total time: " + stopwatchSecondsString + " seconds";
You dont have a variable name in the last line, and if this is all your code, then you dont initialize updatesPerSecond, meaning you dont have a line like
var updatesPerSecond = somenumberhere
If you name your last variable and initialize updatesPerSecond then you should be fine.
However I dont know anything about this website, but I quess it's old. Here is some advice.
You need to tell javascript, that floor is a function from Math so use Math.floor, maybe it works in this website like you did, but keep in mind that you should use it otherwise.
toString() doesnt work like that. Again I dont know if they are using some different methods, but normal js toString() works like number.toString() and u can pass the radix as a parameter, meaning the base of the number representation (2 for binary, 16 for hexadecimal etc.) but this is optional, default is 10 for decimal.
Dont use var as a declaration. Use let instead, if the variable will change, and use const if it wont. In your case you should use let everywhere.
Other thing is that you can use the ++ operator to increment a value by 1, so instead of stopwatchFrame+= 1 just use stopwatchFrame++
And last you shouldn't initialize your default string value as "Nothing", it should be "", an empty string or undefined or null.
I hope this helps, have a good day!
I am new to HTML/CSS/JS and not understanding properly or am missing something completely. I am trying to update the Variable of "CitizenCost" by using Math.pow(2, NumCitizens) that part is working. The part that I am having trouble with is updating CitizenCost to the correct number and having the HTML represent it with the correct number. Right now it updates but it's always behind
IE: it should be X = 2^1 then X = 2^2 So on and so forth
However in the HTML it doesn't update accordingly it is always behind one equation so if the real cost is X = 2^2. The text will show X = 2^1. Unless the Player clicks the button again.
function buycitizen(){
CitizenCost = Math.pow(2, NumCitizens);
document.getElementById("CitizenCost").innerHTML = "Cost of Citizen " + CitizenCost;
if(land >= CitizenCost){
land = land - CitizenCost;
eps = eps + 2;
NumCitizens++;
document.getElementById("NumCitizens").innerHTML = NumCitizens;
}
else
document.getElementById("SystemMessage").innerHTML = "You do not have enough Land Resources to provide for more Citizens right now!";
setTimeout(systemclear, 5000)}
Here is a fiddle demonstrating the issue
https://jsfiddle.net/Traberjkt/yaq0rbad/
Here is the Git
https://github.com/Traberjkt/Conquest
I have tried setting a timer so the text of CitizenCost updates every second. I have thought and tried putting the cost equation in a separate function and re-locating it somewhere else in the function. Sadly I have had no luck figuring this out. Any help or pointing me in the right direction would be greatly appreciated!
Maybe you should make a new function called moreCitizens(howMany):
function moreCitizens(howMany) {
NumCitizens += howMany;
document.getElementById("NumCitizens").innerHTML = NumCitizens;
CitizenCost = Math.pow(2, NumCitizens);
document.getElementById("CitizenCost").innerHTML = "Cost of Citizen " + CitizenCost;
}
Then instead of
NumCitizens++;
you can just write
moreCitizens(1);
and that will update the cost and count fields.
Im working on a betting script and basically have two functions, one for if I win, and one for if I lose. I was wondering, whether any of you guys can help me with the code to be able to count how many times the function has been run,(or how many i have won, and how many times I have lost.)
I was wondering whether it would then be possible to create an element on the page which would display these?
Any help would be great. Im new to javascript and bit unsure how to make variables count??
Let me know if you need more info?
Set up two variables that equal zero, and each time there is a win/loss detected, increment the corresponding value, like so:
var wins = 0,
losses = 0;
function iWin() {
wins += 1;
}
function iLose() {
losses += 1;
}
EDIT:
In order to display your wins/losses, add the following to your html
<p id="wins"></p>
<p id="losses"></p>
And just add two lines of code to the JavaScript code above:
var wins = 0,
losses = 0;
function iWin() {
wins += 1;
document.getElementById('wins').innerHTML = wins;
}
function iLose() {
losses += 1;
document.getElementById('losses').innerHTML = losses;
}
Good luck!
I feel like I'm probably making a fundamental mistake here. I'm hoping someone can help me.
function countdown() {
x = 5;
for (i = x; i > 0; i--) {
document.getElementById('display').innerHTML = (i + " ");
}
}
This is a very small, simple replication of the problem I'm having.
I have a long function. Within that function is a variable, in this case: X.
I want to insert something into an element(in this case: #display) X amount of times.
I figured the best way to do this would be with a for loop, counting down from X by 1 and each time inserting the string I want.
But when it runs, it only returns 1. (I would expect it to return "5 4 3 2 1" in this case).
Please can someone explain to me why this doesn't work? I've been racking my brain over it for hours.
Because you are overwriting the content of the element in each iteration, by assigning a new value to innerHTML. You'd have to append instead:
document.getElementById('display').innerHTML += (i + " ");
// ^
which is the same as
document.getElementById('display').innerHTML =
document.getElementById('display').innerHTML + (i + " ");
And of course it would be much better if you just built the string in the loop and set the content after the loop:
var content = '';
for (i = x; i > 0; i--) {
content += (i + " ");
}
document.getElementById('display').innerHTML = content;
This way you avoid searching for the element in the document on every iteration. But .innerHTML is only useful to some degree, you should also have a look at DOM manipulation functions (such as .appendChild), once you are starting to do more evolved manipulations.