How can I use localStorage for storing clicks - javascript

I am trying to save the amount of clicks on a button in a textbox with localStorage, but whenever I reload the page, all the data is cleared. Here is my code:
var i = 0; // i is the number of clicks. the number of clicks is set to 0
when page is
// loaded.
function countClick() { // The next 3 lines of code are executed when the
Kill a cat // button is clicked
i++;
alert("You have clicked " + i + " cats so far"); // Make message box
localStorage.setItem("count", "i")
document.getElementById("count").value = i ; // Edits the 'clicks clicked'
text box
// Saves number of clicks, so when you close // or open the page, your
progress still exists.
}
function clear() {
document.getElementById("count").value = 0 ;
}
window.onload = function(){
var val = localStorage.getItem('value'); // or localStorage.value
if(val === null)
val = "i";
document.getElementById("myData").value = val;
}
window.onbeforeunload = function(){
localStorage.setItem('value', document.getElementById("myData").value);
localStorage.value = document.getElementById("myData").value
}
Please help.
Thanks to all the other examples from the other people, used in here.

In this function, you reset your localStorage item before page load...
window.onbeforeunload = function(){
localStorage.setItem('value', document.getElementById("myData").value);
localStorage.value = document.getElementById("myData").value
}
It's normal there is no data when you refresh.
Just try somethink more simple like this without other function :
var i = 0;
function countClick() {
i++;
localStorage.setItem("count", i)
document.getElementById("count").value = i ;
}
window.onload = function(){
var val = localStorage.getItem('count');
document.getElementById("count").value = val;
}

Related

How to hide button after 5 clicks jQuery?

In short I have multiple posts and each post have download button with unique data-click attribute,
For example data-click="1" for post 1 download button , data-click="2" for post 2 download button and so on. I want that if download button click 5 times for post 1 then after 5 clicks it hides , also it keeps hidden if refresh the page , I have written some code but it doesn't hide the button
<script>//this script is responsible for adding a unique data-click= 0,1,2,3,4.....n to each resume post respectively.
$(document).ready(function() {
var PostId = 2;
var i = 1;
$('.gotocls').each(function() {
jQuery(this).attr('data-click', i);
var ClickId = $(this).attr('data-click');
var LocalKey = PostId + '+' + ClickId;
if(localStorage.getItem(LocalKey)){
if(localStorage.getItem(LocalKey) == '5'){
$(this).hide();
// alert('im m new here');
}
}
else{
localStorage.setItem(LocalKey,0);
alert('im game');
}
i++
});
});
</script>
the above code add unique data click attribute to each downlaod button and check if localstorage value is 5
<script type="text/javascript">
$(document).ready(function(){
$(".gotocls").click(function() {
var PostId = 2;
var ClickId = $(this).attr("data-click");
var LocalKey = PostId + '+' + ClickId;
count = localStorage.getItem(LocalKey);
count ++;
if(count > 5){
alert(count);
localStorage.setItem(LocalKey, 5);
$(this).hide();
}
else{
alert(count);
alert('imnot here');
localStorage.setItem(LocalKey, count);
}
});
});
</script>
and my html code
<a class="dkpdf-button gotocls" href="javascript:return false;">Download Now</a>
For a better understanding, I set the simple code
HTML
<div>
<button id="gotocls" class="gotocls">Download</button>
</div>
Sctipt
<script type="text/javascript">
$(document).ready(function () {
var LocalKey = "Click_Count"; // set key paramater
count = localStorage.getItem(LocalKey); // get data from local storage
if (count >= 5) //condition - if click count equal or greater than 5
{
$(".gotocls").hide(); // button hide
}
$(".gotocls").click(function () {
//var PostId = 2;
//var ClickId = $(this).attr("data-click");
count++;
if (count >= 5) {
alert(count);
localStorage.setItem(LocalKey, 5);
$(this).hide();
}
else {
alert(count);
alert('imnot here');
localStorage.setItem(LocalKey, count);
}
});
});
</script>
you can change javascript as per your requirements, this will work on client-side

JS: setInterval running as if there were multiple intervals set

So, I've been trying to figure out JS, and what better way to do so than to make a small project. It's a small trivia game, and it has a question timer I've made using setInterval. Unfortunately, after answering multiple questions, the interval's behaviour gets very weird - it runs the command twice every time. I guess it's my faulty implementation of buttonclicks?
By the way, if my code is awful I am sorry, I've been desperate to fix the issue and messed with it a lot.
function startGame(){
if (clicked === true){
return;
}
else{
$("#textPresented").html("Which anthem is this?");
$("#button").css("display", "none");
currentCountry = getRndInteger(0,8);
console.log(currentCountry);
var generatedURL = anthemnflags[currentCountry];
console.log(generatedURL);
audios.setAttribute("src", generatedURL);
audios.play();
$("#button").html("I know!");
$("#button").css("display", "block");
$("#button").click(function () {
continueManager();
});
y=10;
console.log("cleared y" + y);
x = setInterval(function(){
y = y - 1;
console.log("Counting down..." + y)
}, 1000);
console.log("INTERVAL SET");
}
}
Here is the console output:
cleared y10 flaggame.js:59:17
INTERVAL SET flaggame.js:64:17
AbortError: The fetching process for the media resource was aborted by the user agent at the user's request. flaggame.js:49
Counting down...9 flaggame.js:62:20 ---- THESE TWO ARE BEING PRINTED AT THE SAME TIME
Counting down...8 flaggame.js:62:20 ---- THESE TWO ARE BEING PRINTED AT THE SAME TIME
Counting down...7 flaggame.js:62:20
Counting down...6 flaggame.js:62:20
Counting down...5 flaggame.js:62:20
Counting down...4 flaggame.js:62:20
Counting down...3 flaggame.js:62:20
Counting down...2 flaggame.js:62:20
Counting down...1 flaggame.js:62:20
Counting down...0
THE REST OF MY CODE:
function middleGame(){
$("#button").css("display", "none");
var n = document.querySelectorAll(".flagc").length;
correctIMG = getRndInteger(0,n-1);
showFlags();
var taken = new Array();
for (var i = 0; i < n; ++i){
if (i === correctIMG){
images[i].attr("src", "res/" + flagsfiles[currentCountry]);
taken[currentCountry] = true;
}
else{
var randomFlag = getRndInteger(0, flagsfiles.length);
if (randomFlag !== currentCountry && taken[randomFlag] !== true){
images[i].attr("src", "res/" + flagsfiles[randomFlag]);
taken[randomFlag] = true;
}
}
}
$(".flagc").click(function(){
clickregister(this);
});
}
function continueManager(){
if (!clicked){
audios.pause()
clearInterval(x);
x = 0;
clicked = true;
middleGame();
return;
}
}
function clickregister(buttonClicked){
if ($(buttonClicked).attr("id") != correctIMG){
points = points - 1;
flagARR[$(buttonClicked).attr("id")].css("display", "none");
console.log("INCORRECT");
}
else{
if (y >= 0) {
var addedPoints = 1 + y;
points = points + addedPoints;
$("#points").html(points);
}
else{
points = points + 1;
}
hideFlags();
clicked = false;
startGame();
}
}
$(function(){
hideFlags();
$("#textPresented").html("When you're ready, click the button below!");
$("#button").html("I am ready!");
$("#button").click(function () {
if (!gameStarted){
gameStarted = true;
alert("STARTING GAME");
startGame();
}
});
});
Basically this is how it works:
When the "I am ready" button is clicked, startGame() is called. It plays a random tune and counts down, until the player hits the "I know" button. That button SHOULD stop the interval and start the middleGame() function, which shows 4 images, generates a random correct image and awaits input, checks if it's true, then launches startGame() again.
The first and second cycles are perfect - after the third one things get messy.
I also noticed that the "INCORRECT" log gets printed twice, why?
EDIT: here is the minimized code that has the same issue:
var x;
var gameStarted = false;
var y;
var clicked;
$(function(){
$("#button").click(function () {
if (!gameStarted){
gameStarted = true;
startGame();
}
});
});
function startGame(){
console.log("startgame()");
if (clicked === true){
return;
}
else{
console.log("!true");
$("#button").css("display", "block");
$("#button").click(function () {
continueManager();
});
y=10;
x = setInterval(function(){
y = y - 1;
console.log(y);
}, 1000);
}
}
function continueManager(){
if (!clicked){
clearInterval(x);
x = 0;
clicked = true;
middleGame();
return;
}
}
function middleGame(){
$("#button").css("display", "none");
var taken = new Array();
$(".flagc").click(function(){
clickregister(this);
});
}
function clickregister(buttonClicked){
console.log("clickgregister");
//Irrelevant code that checks the answers
clicked = false;
startGame();
}
EDIT2: It appears that my clickregister() function gets called twice, and that function then calls startGame() twice.
EDIT3: I have found the culprit! It's these lines of code:
$(".flagc").click(function(){
console.log("button" + $(this).attr("id") + "is clicked");
clickregister(this);
});
They get called twice, for the same button
I fixed it!
It turns out all I had to do was to add
$(".flagc").unbind('click');
Before the .click() function!
You need to clear the interval first then call it again. You can do that by creating a variable outside of the event listener scope and in the event listener check if the variable contains anything if yes then clear the interval of x. After clearing the interval you can reset it.
Something like this:
<button class="first" type="submit">Button</button>
const btn = document.querySelector('.first');
let x;
btn.addEventListener("click", () => {
x && clearInterval(x)
x = setInterval(() => console.log("yoo"), 500)
})
This is because if you don't clear the interval of x it will create a new one on every button press.

looping through array content with a delay

this is a jquery/ javascript problem.
So I have an array that contains button numbers and outputs those buttons onto a button which will result in the button being clicked. The problem is that all the buttons get clicked at once if I run the loop. Instead I want it to output the numbers with a delay so that the buttons will be pressed after a 1 second delay.
Here is the link to the Simon game project:
https://codepen.io/roger1891/full/vmYqwx/
The problem is visible after following the 1st button. After that, the computer will press the next 2 buttons at the same time instead of pressing them separately after a 1 sec delay.
The problem is located in this loop which is located in the myloop() function:
sequenceArray.forEach(function(item, index, array){
//click button by getting the last index of the array
//$("#btn-"+array[array.length-1]).click();
$("#btn-"+array[index]).click();
console.log(array);
});
This is the full code:
//associating buttons to sound
var soundButton = function(buttonId, soundId) {
$("#" + buttonId).click(function(){
$("#" + soundId).get(0).play();
$("#" + buttonId).css("opacity", "0.5");
setTimeout( function(){
$("#" + buttonId).css("opacity", "1");
},500);
if(currentPlayerTurn == "human") {
var $input = $(this);
var attrString = $input.attr("id");
//only get number from id attribute
var strNum = attrString.replace( /^\D+/g, '');
//convert theNumber from string to number
var theNum = parseInt(strNum);
playerArray.push(theNum);
console.log(theNum);
console.log(playerArray);
}
});
};
function myLoop() {
setInterval( function(){
if(gameWon == false && onGoingGame == true && currentPlayerTurn == "computer" && score < 5) {
//increment score
score++;
//append to score id
$("#score").empty().append(score);
//create random number
randomNumber = Math.floor((Math.random()*4) + 1);
//push random number into array
sequenceArray.push(randomNumber);
//loop through array
sequenceArray.forEach(function(item, index, array){
//click button by getting the last index of the array
//$("#btn-"+array[array.length-1]).click();
$("#btn-"+array[index]).click();
console.log(array);
});
currentRound = sequenceArray.length;
onGoingGame = false;
currentPlayerTurn = "human";
}
if(currentPlayerTurn == "human") {
var is_same = playerArray.length == sequenceArray.length && playerArray.every(function(element, index) {
return element === sequenceArray[index];
});
is_same;
console.log(is_same);
if(is_same == true) {
playerArray = [];
onGoingGame = true;
currentPlayerTurn = "computer";
}
}
},1000);
}
myLoop();
Thank you in advance for your help.
Since you want to trigger the buttons one by one, your setTimeout() should be inside the loop. Be mindful of the index, since this is async.
sequenceArray.forEach(function(item, index, array) {
// set a timeout so each second one button gets clicked
setTimeout( (function( index ) {
// use a closure here so that our index values stay correct.
return function() {
$("#btn-"+array[index]).click();
};
}( index )), (1000 * index) );
});
edit: replaced the fixed 1000ms delay to delay * index
You need to console.log(item) instead of full array in forEach loop

Javascript game - increment fires more than once

I am building simple "Spot the difference" game in jQuery/HTML. There are 5 rounds/stages, each with different pictures and user needs to go through all of them starting from round 1.
I am having this issue with increment firing twice when I am in 2nd round, and then triple times when I am in 3rd round and so on. This cause points to jump up double/triple/... instead of just jump up by 1.
The code is on baby level. I did not make any stuff to refactor it and improve.
I think I don't need to provide HTML for this, as simply looking at logic in JS file should be enough.
For those who prefer pastebin version is here (http://pastebin.com/ACqafZ5G). Full code:
(function(){
var round = 1;
var points = 0;
var pointsTotal = 0;
var pointsDisplay = $(".js-calc");
var pointsTotalDisplay = $(".js-calc-total");
var counterDisplay = $(".js-counter");
var entryPage = $(".entry-page");
var mainMenu = $(".main-menu");
var submitNow = $(".js-now");
var submitResultsFinalBtn = $(".js-submit-results-final");
// rounds-categories
var allRounds = $(".round");
var divRound1 = $(".round1"),
divRound2 = $(".round2"),
divRound3 = $(".round3"),
divRound4 = $(".round4"),
divRound5 = $(".round5");
var allPic = $(".js-pic");
var pic1 = $(".js-pic1"),
pic2 = $(".js-pic2"),
pic3 = $(".js-pic3"),
pic4 = $(".js-pic4"),
picFinish = $(".js-finish");
// on the beginning hide all and leave only entry page
mainMenu.hide();
allRounds.hide();
submitResultsFinalBtn.hide();
// countdown (SEE THE FUNCTION ON THE END)
var myCounter = new Countdown({
seconds: 60, // number of seconds to count down
onUpdateStatus: function(sec){
counterDisplay.html(sec); // display seconds in html
}, // callback for each second
onCounterEnd: function(){
console.log('TIME IS OVER!');
// THIS SHOULD NOT BE HERE, I WOULD PREFER TO MOVE IT SOMEWHERE TO GAME ITSELF
pointsTotalDisplay.html(pointsTotal);
round++; // update to next round
allRounds.hide(); // hide window
mainMenu.show(); // show back again main menu
} // final action
});
var initiateRound = $(".js-initiate");
initiateRound.on("click", function(){ // START GAME
console.log("ROUND " + round + " INITIATED");
points = 0; // reset the points for this round to 0 - not sure this is the way to do it...
console.log(points + " points for this round, " + pointsTotal + " in TOTAL"); // say how many points so far
entryPage.hide();
mainMenu.hide();
allPic.hide();
if( round === 1){
divRound1.show();
pic1.show();
}else if( round === 2){
divRound2.show();
pic2.show();
}else if( round === 3){
divRound3.show();
pic3.show();
}else if( round === 4){
divRound4.show();
pic4.show();
}else if( round === 5){
divRound5.show();
picFinish.show();
initiateRound.hide();
submitNow.hide();
submitResultsFinalBtn.show();
}
counterDisplay.html("60"); //display 60sec on the beginning
myCounter.start(); // and start play time (countdown)
// pointsDisplay.html(points); // display in HTML amount of points for particular round
// if user start collecting points, add them
var mapImage = $('.transparent AREA');
mapImage.each(function(index) {
// When clicked, reveal red circle with missing element
$(this).one("click", function(e) { // YOU CAN CLICK ONLY ONCE!! Using .one() to prevent multiple clicks and eventually scoring more points
e.stopPropagation();
console.log("FIRED");
var theDifference = '#'+$(this).attr('id')+'-diff';
$(theDifference).css('display', 'inline');
if ($(theDifference).data('clicked', true)){ // found circle
// points++;
points += 1;
pointsTotal++;
console.log(points + " points for this round, " + pointsTotal + " in TOTAL");
pointsDisplay.html(points); // display in html amount of points
}
if (points === 6){ // if all points collected (max 6) for this round
myCounter.stop(); // stop countdown
console.log("time stopped, you found all");
setTimeout(function(){ // give him 2sec delay to see last circle marked
allRounds.hide(); // hide window
mainMenu.show(); // show back again main menu
console.log("round " + round + " is finished");
round++; // update to next round
console.log("round " + round + " is activated");
pointsTotalDisplay.html(pointsTotal); // display in HTML total amount of pints
}, 2000);
};
});
});
});
})();
function Countdown(options) {
var timer,
instance = this,
seconds = options.seconds || 10,
updateStatus = options.onUpdateStatus || function () {},
counterEnd = options.onCounterEnd || function () {};
function decrementCounter() {
updateStatus(seconds);
if (seconds === 0) {
counterEnd();
instance.stop();
}
seconds--;
}
this.start = function () {
clearInterval(timer);
timer = 0;
seconds = options.seconds;
timer = setInterval(decrementCounter, 1000);
};
this.stop = function () {
clearInterval(timer);
};
}
Are you sure you're not stacking the $('.transparent AREA') from a round to another ?
This would explain why you score multiple times:
var mapImage = $('.transparent AREA');
mapImage.each(function(index) {
// ...
points++;
// ...
});
Solved!
mapImage.each should be outside of initiateRound

How do I make text inside the title tag animate using JavaScript?

How do I show a scrolling (moving) message in the title?
<title>Welcome to Some title</title>
Translate the titlebar into a dynamic that displays additional information using JavaScript (without any CSS).
Here's an eye catching example to get your visitors back when your web page tab is not active within the browser (onblur). This script will animate the original title text with an intro, the original title text is restored when the tab is returned to active state (focus). When the tab is clicked the original page title is restored. For social media sharing it is highly recommended to include the original page title text with the prefaced animated text (onblur).
$(function() {
var origTitle, animatedTitle, timer;
function animateTitle(newTitle) {
var currentState = false;
origTitle = document.title; // save original title
animatedTitle = "Hey There! " + origTitle;
timer = setInterval(startAnimation, 2000);
function startAnimation() {
// animate between the original and the new title
document.title = currentState ? origTitle : animatedTitle;
currentState = !currentState;
}
}
function restoreTitle() {
clearInterval(timer);
document.title = origTitle; // restore original title
}
// Change page title on blur
$(window).blur(function() {
animateTitle();
});
// Change page title back on focus
$(window).focus(function() {
restoreTitle();
});
});
You can add marque in the title bar text through JavaScript. See it in the blog post Add Scrolling Marquee Effects Text to Title Bar.
The unmodified contents of that page, except for the formatting:
/*
Now you can add moving text to title bar of browser for your website or blog.
Here is the code to do this. Add this code in your website or blog in a widget
(after replacing YOUR TEXT with your desired text).
*/
<script language=javascript>
var rev = "fwd";
function titlebar(val){
var msg = "YOUR TEXT";
var res = " ";
var speed = 100;
var pos = val;
msg = " |-"+msg+"-|";
var le = msg.length;
if(rev == "fwd"){
if(pos < le){
pos = pos+1;
scroll = msg.substr(0,pos);
document.title = scroll;
timer = window.setTimeout("titlebar("+pos+")",speed);
}
else {
rev = "bwd";
timer = window.setTimeout("titlebar("+pos+")",speed);
}
}
else {
if(pos > 0) {
pos = pos-1;
var ale = le-pos;
scrol = msg.substr(ale,le);
document.title = scrol;
timer = window.setTimeout("titlebar("+pos+")",speed);
}
else {
rev = "fwd";
timer = window.setTimeout("titlebar("+pos+")",speed);
}
}
}
titlebar(0);
</script>
Here's another one. Only goes forward though...
To use: Link to the file and write this line of code
var title = new MovingTitle("Desired title... ", 300, 10);
title.init();
First parameter is the desired text, next one is the update interval, 10 is the number of visible letters...
function MovingTitle(writeText, interval, visibleLetters) {
var _instance = {};
var _currId = 0;
var _numberOfLetters = writeText.length;
function updateTitle() {
_currId += 1;
if(_currId > _numberOfLetters - 1) {
_currId = 0;
}
var startId = _currId;
var endId = startId + visibleLetters;
var finalText;
if(endId < _numberOfLetters - 1) {
finalText = writeText.substring(startId, endId);
} else {
var cappedEndId = _numberOfLetters;
endId = endId - cappedEndId;
finalText = writeText.substring(startId, cappedEndId) + writeText.substring(0, endId);
}
document.title = finalText;
}
_instance.init = function() {
setInterval(updateTitle, interval);
};
return _instance;
}
heres mine:
function animateTitle(Title = "Hello, World!", delay = 300) {
let counter = 0;
let direction = true;
aniTitle = setInterval(function () {
if (counter == Title.length)
direction = false;
if (counter == false)
direction = true;
counter = (direction == true) ? ++counter : --counter;
newtitle = (counter == 0) ? " " : Title.slice(0, counter);
document.title = newtitle;
}, delay)
}

Categories

Resources