localStorage not working to "save" game - javascript

Good day!
Complete JS noob here. I was following this tutorial: http://dhmstark.co.uk/incrementals-part-2.html regarding saving and loading the game. However, it is not working at all. I was hoping you fine folks might be able to easily tell me the issue with the code. There are no errors coming up on the browser console at all. But, when I re-load the page, it is not loading the "saved" data. I have tried putting the load() function within the js file itself, as well as including in the HTML header. I have also tried calling the load() function with a window.onload within the script itself.
Please help.
HTML
<!DOCTYPE HTML>
<head>
<title> Game </title>
<link rel="stylesheet" type="text/css" href="interface.css" />
<script type="text/javascript">
function load() {
var savegame = JSON.parse(localStorage.getItem("save"));
if (typeof savegame.clicks !== "undefined") clicks = savegame.clicks;
}
</script>
</head>
<body onload="load()">
<button onClick="increment(1)"> Click </button>
<span id="clicks"></span><br /><br />
<button onClick="buyThing()"> Buy Thing </button><br />
Things: <span id="things">0</span><br />
Next Thing Cost: <span id="thingCost">10</span>
<script type="text/javascript" src="main.js"></script>
</body>
JS
//click tracker
var clicks = 0;
function increment(number){
clicks = clicks + number;
document.getElementById("clicks").innerHTML = clicks;
};
//cursor
var things = 0;
function buyThing(){
var thingCost = Math.floor(10 * Math.pow(1.1, things)); //works out cost of this cursor
if(clicks >= thingCost){ //check that player has enough clicks to afford cursor
things = things + 1; //increase number of cursors
clicks = clicks - thingCost; //remove clicks spent
document.getElementById('things').innerHTML = things; //update the number of cursors for the user
document.getElementById('clicks').innerHTML = clicks; //update the number of clicks for the user
};
var nextCost = Math.floor(10 * Math.pow(1.1,things)); //works out the cost of the next cursor
document.getElementById('thingCost').innerHTML = nextCost; //updates the cursor cost for user
};
var save = {
clicks: clicks,
things: things,
}
//loop
window.setInterval(function(){
increment(things);
localStorage.setItem("save",JSON.stringify(save));
}, 1000);

Your save object will be declared and defined only once and never be changed, so you will be saving over and over again the first initial value of the progress, you should save a newly object on each interval:
window.setInterval(function(){
increment(things);
localStorage.setItem("save",JSON.stringify({clicks: clicks, things: things}));
}, 1000);

You are getting a reference issue. The memory addresses of clicks and save.clicks are not pointing to the same thing, since it's a primitive number.
Putting all your game data into a single object will help reduce the global namespace pollution as well.
<!DOCTYPE HTML>
<head>
<title> Game </title>
<link rel="stylesheet" type="text/css" href="interface.css" />
<script type="text/javascript">
function load() {
return JSON.parse(localStorage.getItem("game")) || {
clicks: 0,
things: 0
};
}
</script>
</head>
<body onload="load()">
<button onClick="increment(1)"> Click </button>
<span id="clicks"></span><br /><br />
<button onClick="buyThing()"> Buy Thing </button><br />
Things: <span id="things">0</span><br />
Next Thing Cost: <span id="thingCost">10</span>
<script type="text/javascript" src="main.js"></script>
JS
//click tracker
var game = load();
function increment(number){
game.clicks += number;
document.getElementById("clicks").innerHTML = game.clicks;
};
//cursor
function buyThing(){
var thingCost = Math.floor(10 * Math.pow(1.1, game.things)); //works out cost of this cursor
if(game.clicks >= thingCost){ //check that player has enough clicks to afford cursor
game.things++; //increase number of cursors
game.clicks -= thingCost; //remove clicks spent
document.getElementById('things').innerHTML = game.things; //update the number of cursors for the user
document.getElementById('clicks').innerHTML = game.clicks; //update the number of clicks for the user
};
var nextCost = Math.floor(10 * Math.pow(1.1,game.things)); //works out the cost of the next cursor
document.getElementById('thingCost').innerHTML = nextCost; //updates the cursor cost for user
};
//loop
window.setInterval(function(){
increment(game.things);
localStorage.setItem("game",JSON.stringify(game));
}, 1000);

Related

Increment & Decrement not working as intended in Javascript

The unexpected behavior I'm getting is when clicking the donate or undonate button. It takes 2 clicks initially for the tracker to display the incremented or decremented number despite the color change happening immediately. Once it does change the number on the second click, the 3rd click and on using the same button will work normally to increment or decrement.
In addition to that, if you switch the button you're clicking to the other, it still performs the previous action first.Hopefully this explanation of the issue makes sense. Appreciate any direction that can be given as I am still new!
HTML:
<!DOCTYPE html>
<head>
<link rel="stylesheet" href='style.css' />
<title>Front-End Portfolio Project</title>
</head>
<body>
<h1>Donate Food 2 Me</h1>
<p id="container"></p>
<p id='caption'>food quantity</p>
<button id="donate">Donate</button>
<button id="undonate">Un-Donate</button>
<script type="text/javascript" src='main.js'></script>
</body>
</html>
JS:
const donateButton = document.getElementById("donate");
const unDonateButton = document.getElementById("undonate");
const tracker = document.getElementById("container");
var i = 0;
tracker.innerHTML = i;
donate = function(){
donateButton.style.backgroundColor = 'red';
tracker.innerHTML = i++;
}
undonate = function(){
unDonateButton.style.backgroundColor = 'blue';
tracker.innerHTML = i--;
}
donateButton.addEventListener("click", donate);
unDonateButton.addEventListener("click", undonate);
The only mistake you made is ignoring the difference between i++ and ++i (i-- and --i).
Change your code as below (You can see the result here):
donate = function(){
donateButton.style.backgroundColor = 'red';
tracker.innerHTML = ++i;
}
undonate = function(){
if (i > 0) {
unDonateButton.style.backgroundColor = 'blue';
tracker.innerHTML = --i;
}
}

How to do an action when a variable hits a specific number javascript

So basically I have done this code down bellow and I am trying to have a button that adds 1 to a variable and when that variable hits the specific number it plays an action. My final goal is to make it so when the variable hits the specific number it redirects to another page. I have tried for way too long and my friends don't know the solution either.
<!DOCTYPE html>
<head> </head>
<!DOCTYPE html>
<html>
<head>
<title> click tester </title>
<Meta charset="utf-8">
</head>
<body>
<script>
var theClicks = 1;
const win = 25;
if(theClicks >= win) {
alert('over 25');
}
</script>
<button onclick=theClicks++;>Button that adds1 to variable</button>
</body>
</html>
<button onclick=theClicks++;>Button that adds1 to variable</button>
Just increments the variable. To expand that you could add more actions in the button onclick event, but it's much better to just put it all in a function you can call.
<script>
var theClicks = 1;
const win = 25;
function doThing() {
if (++theClicks >= win) {
alert('over 25');
}
}
</script>
<button onclick='doThing()'>Button that adds1 to variable</button>
You could take an approach like below. Basically create a function that keeps track of a counter variable (i.e., i). Next add a click event listener to the button and increment the counter on each click. When the counter reaches 25 then do some action (I made it only needed to be clicked 3 times in the code below for demo convenience) .
For example:
// Reference to the DOM elements
const countEl = document.querySelector('#count-el');
const buttonEl = document.querySelector('button');
// Init a counter variable and return a function that increments it
const increment = (() => {
let i = 1;
return () => i++;
})();
// The click event listener
buttonEl.addEventListener('click', () => {
// Increment the count and update the UI if current click count is 3
if (increment() === 3) {
countEl.textContent = 'Do action now!';
}
});
<span id="count-el"></span>
<br />
<button>Click 3 times to do action</button>

clearInterval() not working on clock timer with JavaScript

I am very new to JavaScript and programming in general. I am currently in a little pickle with some code that I am playing around with, and I am wondering if anyone can give me some advice.
Background:
The code I am working with is rather simple; There is a clock with the current time running on setInterval to update by the second.
Below the clock there is a button that reads “Stop,” and when pressed, it will clear the Interval and the button will then read “Start.” If the button, which reads “Start” is pressed again, it will continue the clock timer in its current time. So basically this one button toggles the interval of the clock, and depending on which state it is, the button will read “Start” or “Stop.”
W3Schools: JS Timing is where I am originally referencing when creating the code I am working with. This is where I am learning about how setInterval and clearInterval works. I also took some of the code in the examples and adjusted it so I can try to make the clock timer toggle off and on.
Code:
var clock09 = window.setInterval(myTimer09, 1000);
function myTimer09() {
var d = new Date();
var t = d.toLocaleTimeString();
document.getElementById("req09").innerHTML =
"<h1>" + t + "</h1>";
}
function toggle10() {
var button = document.getElementById("button10").innerHTML;
if (button == "Stop") {
window.clearInterval(clock09);
document.getElementById("button10").innerHTML = "Start";
} else {
clock09 = window.setInterval(myTimer09, 1000);
document.getElementById("button10").innerHTML = "Stop";
}
}
<span class="center" id="req09"></span>
<button type="button" id="button10" onclick="toggle10()" class="button">Stop</button>
https://jsfiddle.net/dtc84d78/
Problem:
So my problem with the code is that the button toggles from a “Stop” button to a “Start” button, but the clearInterval is not applying to the Variable with the setInterval.
I have googled similar problems in SO, such as this one, and I followed their advice, and still nothing. After hours of trying to figure out, I decided to just copy and paste some example from W3Schools straight to jsFiddle, and that didn’t even work (included in jsfiddle link)?
I am really just going crazy on why anything with clearInterval() is not working with me? Could it be my computer, browser or anything else? I am coming to SO as my last resource, so if anyone can give me some guidance to this problem, I will name my first child after you.
Thank you in advance.
Extra Info:
I am currently working on a Mac desktop, using Komodo to write the code, and I am using Google Chrome to preview the code.
UPDATE:
I mentioned this in the comments, but coming in the code was in an external .js file. The .js file was then linked in between the head tags, and right before the end body tag.
<head>
<meta charset="utf-8" />
<title>Program</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="css/normalize.css">
<link rel="stylesheet" href="css/program-05.css">
<script type="text/javascript" src="scripts/program-05.js">
/* <![CDATA[ */
/* ]]> */
</script>
</head>
<body onload="checkCookies(); setTimeout(function() { func11() }, 5000);">
. . . code for stuff
. . . code for clock timer
. . . code for other stuff
<script type="text/javascript" src="scripts/program-05.js">
/* <![CDATA[ */
/* ]]> */
</script>
</body>
After #Matz mentioned to stick the clock timer js code in the head section, the code worked great! This is what it looks like so far in the head section.
<head>
<meta charset="utf-8" />
<title>Program</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="css/normalize.css">
<link rel="stylesheet" href="css/program-05.css">
<script type="text/javascript" src="scripts/program-05.js">
/* <![CDATA[ */
/* ]]> */
</script>
<script>
///*
var clock09 = window.setInterval(myTimer09, 1000);
function myTimer09() {
var d = new Date();
var t = d.toLocaleTimeString();
document.getElementById("req09").innerHTML =
"<h1>" + t + "</h1>";
}
function toggle10() {
var button = document.getElementById("button10").innerHTML;
if (button == "Stop") {
window.clearInterval(clock09);
document.getElementById("button10").innerHTML = "Start";
} else {
clock09 = window.setInterval(myTimer09, 1000);
document.getElementById("button10").innerHTML = "Stop";
}
}
//*/
</script>
</head>
Though this works great, I now want to figure out as to why the clock timer js code works when it is directly in the head section as compared to keeping it in the external .js file (with the external file being linked in the doc)? What can I do to make it work within the external file?
Problem:
This is because the default Load Type is set to onLoad which is wrapping your javascript code in window.onload = function() {} hence the scope of your function was getting limited to the onload function and it wasn't available outside:
Solution:
Click on the Javascript setting in the Javascript section of the Fiddle, change it to No wrap - in body and it will work since this will now place your Javascript code in the body tag.
Additional Note:
Your code is also working via StackOverflow snippet:
/*My Problem*/
var clock09 = window.setInterval(myTimer09, 1000);
function myTimer09() {
var d = new Date();
var t = d.toLocaleTimeString();
document.getElementById("req09").innerHTML =
"<h1>" + t + "</h1>";
}
function toggle10() {
var button = document.getElementById("button10").innerHTML;
if (button == "Stop") {
window.clearInterval(clock09);
document.getElementById("button10").innerHTML = "Start";
} else {
clock09 = window.setInterval(myTimer09, 1000);
document.getElementById("button10").innerHTML = "Stop";
}
}
/*W3S Problem*/
var myVar = setInterval(myTimer, 1000);
function myTimer() {
var d = new Date();
document.getElementById("demo").innerHTML =
d.toLocaleTimeString();
}
<!-- My Problem -->
<span class="center" id="req09"></span>
<button type="button" id="button10" onclick="toggle10()" class="button">Stop</button>
<hr>
<hr>
<!-- W3S Problem -->
<p id="demo"></p>
<button onclick="clearInterval(myVar)">Stop time</button>
Recommendation
Separation of concerns
I'll recommend you moving your javascript code in the external file and later include them in your HTML using script tag. So for example, you moved your code in app.js then include that in your HTML as:
<!-- make sure the path here is relative to the current HTML -->
<script src="./app.js"></script>
One way to fix the timer starting and stopping is to move the javascript in between the HEAD tags so the functions are declared by the time the html loads. I made this work:
<html>
<head>
<title>Stuff</title>
<script >
var clock09 = window.setInterval(myTimer09, 1000);
.... your code
</script>
</head>
<body>
<span class="center" id="req09"></span>
<button type="button" id="button10" onclick="toggle10()" class="button">Stop</button>
</body>
</html>
You are declaring a new date variable in the myTimer09 function, so every time it is called, it shows the current time. You should declare the time outside the function, then pass it to the function. When you stop the timer, you should save the time value so that you can restart with that value.
This seems to be an issue with JSFiddle.
The onclick handler is looking for window.toggle10 which isn't actually defined (check for the error in the console).
It seems that this is something others have seen with JSFiddle
I've C&Ped your code in to a JSbin and it works as described!

new mail counter javascript

I am having some major problems with a javascript app I'm working on. I want my window to open to a closed envelope and then after five seconds to change to an open envelope with a little 1 counter in the corner of it. I want the counter to continue to move up every five seconds unless the envelope is clicked. If clicked I want the count to start over. So far I have only gotten my closed envelope showing up. I'm new and have no idea what I am doing wrong so any help would be awesome!
My html:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="mail.js"></script>
</head>
<body>
<img id"closed" src="closed.png" onclick="resetTimer()">
<span id="counter"></span>
</body>
</html>
And my JavaScript:
window.onload = function(){
var counter = 0;
var timer = setInterval(
function(){
counter++;
document.getElementById("demo").firstChild.nodeValue = counter;
},
5000
);
function openEnvelope(){
var img = document.getElementById("picture");
if (counter > 1){
img.src = "open.png"
}
}
open = setTimeout("open()", 1000);
function resetTimer(){
clearInterval(timer);
}
}
You need to increment your counter and set the counter span to have that value :
var counter = 0;
//Create your timer (setTimeout will only run once, setInterval will start again once run.
//1000 = 1 second
var timer = setInterval(openEnvelope, 1000);
function openEnvelope() {
var img = document.getElementById("picture");
var counterSpan = document.getElementById("counter");
if (counter > 1) {
img.src = "open.png"
counterSpan.innerHTML = counter;
}
//Add 1 to Counter
counter++;
}
function resetTimer() {
clearInterval(timer);
counter = 0;
}
This will run your openEnvelope function every second, and if the counter value is more than 1 it will set the Img Source to be open.png and the counter span to have the counters value. On the click of the Envelope it will clear the timer and reset the counter.
And your HTML will become :
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="mail.js"></script>
</head>
<body>
<img id"picture" src="closed.png" onclick="resetTimer()">
<span id="counter"></span>
</body>
</html>
Here is a working JSFiddle for your problem, try creating a blank page and copying the HTML straight into the <body> tag and the Javascript into <script></script> tags in the <head> of your page.

Conversion Tag on Event

I am trying to get a conversion pixel on a button tag, I want this pixel to fire when a user agrees to hit the submit button, and the URL does not change (just a thank you message pops up on the page). I already have a conversion tag on the page, but want to count those that hit this action button separately. Any help would be appreciated.
<html>
<body>
click here
<script language="javascript">
<!--
function ftGoalTag19212(){
var ftRand = Math.random() + "";
var num = ftRand * 1000000000000000000;
var ftGoalTagPix19212 = new Image();
ftGoalTagPix19212.src = "http://servedby.flashtalking.com/spot/2531;19212;1515/?spotName=Demo_Thank_You&cachebuster="+num;
ftGoalTagPix19212.onload = ftLoaded19212;
}function ftLoaded19212() {
top.location.href="http://www.UrlGoesHere.pdf";
}
// -->
</script>
</body>
</HTML>

Categories