I am currently attempting to learn Javascript and starting with a very basic incremental game where you click a button and it increases. I implemented a save button that properly saves to local storage, however upon refresh, it gets reset.
This is the local storage after hitting save, however, it gets reset to 0 when the page is refreshed.
I wanted to implement save functionality in the following way (see loadGame() and saveGame()):
// JavaScript Document
var saveState = {
food: 0
};
var GlobalFood = 0;
window.onunload = saveGame();
window.onload = loadGame();
function loadGame(){
var loadSaveStateString = localStorage.getItem('saveState');
saveState = JSON.parse(loadSaveStateString);
}
function saveGame(){
var saveStateString = JSON.stringify(saveState);
localStorage.setItem('saveState', saveStateString);
}
function tutorialFoodBtnFunc() {
var fVal = document.getElementById("GlobalFood");
GlobalFood++;
fVal.innerHTML = GlobalFood;
saveState['food'] = GlobalFood;
}
function tutorialFoodBtnFunc2() {
var fVal = document.getElementById("GlobalFood");
if(GlobalFood < 1)
{
var foodError = document.getElementById("foodErrorText");
foodError.classList.add("fade-in");
setTimeout(function (){
foodError.classList.remove("fade-in");
}, 2000)
}
else
{
GlobalFood--;
fVal.innerHTML = GlobalFood;
saveState.food = GlobalFood;
}
}
Here's my HTML as well if it's relevant:
<html>
<head>
<meta charset="utf-8">
<title>Wilderness</title>
<link rel="stylesheet" href="styling/tutorial.css">
<script src="js/main.js"></script>
</head>
<div id="page-wrapper">
<body>
<div id="nav">
<p class="GlobalVals">Foodstuffs: </p><span class="GlobalVals" id = "GlobalFood">0</span>
</div>
<div id="tutorialBody">
<button id="tutorialFoodBtn" onclick="tutorialFoodBtnFunc()">Gather Berries</button>
<button id="tutorialFoodBtn2" onclick="tutorialFoodBtnFunc2()">Eat Berries</button>
<p id="foodErrorText">You have no berries!!!</p>
<button id="tutorialFoodBtn2" onclick="saveGame()">Save!!</button>
</div>
</body>
</div>
</html>
First of all, onunload and onload should reference a function. (What you did is execute the function)
window.onunload = saveGame;
window.onload = loadGame;
Then, your code is properly loading the saveState, but you're not assigning it to your GlobalFood variable.
function loadGame(){
var loadSaveStateString = localStorage.getItem('saveState');
saveState = JSON.parse(loadSaveStateString);
GlobalFood = saveState.food;
var fVal = document.getElementById("GlobalFood");
fVal.innerHTML = GlobalFood;
}
Related
I received this code from another user in this forum.
Issue: As seen in the below screenshot, the search results (or data) starts to appear when you click or start typing in the search box or else only the search box loads without the data.
Requirement: I want to display the results (or data) as the page loads.
The code is given below
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#4.5.3/dist/css/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
<style>
.nav-link {
cursor: pointer;
}
</style>
</head>
<body>
<div class="container">
<ul class="nav nav-tabs">
<li class="nav-item">
<div class="nav-link"id="search-link">Search</div>
</li>
</ul>
<div id="app"></div>
<!-- Content here -->
</div>
<!-- Option 1: jQuery and Bootstrap Bundle (includes Popper) -->
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#4.5.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ho+j7jyWK8fNQe+A12Hb8AhRq26LrZ/JpcUGGOn+Y7RsweNrtN/tE3MoK7ZeZDyx" crossorigin="anonymous"></script>
<script>
var data;
function loadView(options){
var id = typeof options.id === "undefined" ? "app" : options.id;
var cb = typeof options.callback === "undefined" ? function(){} : options.callback;
google.script.run.withSuccessHandler(function(html){
document.getElementById("app").innerHTML = html;
typeof options.params === "undefined" ? cb() : cb(options.params);
})[options.func]();
}
function setDataForSearch(){
google.script.run.withSuccessHandler(function(dataReturned){
data = dataReturned.slice();
}).getDataForSearch();
}
function search(){
var searchinput = document.getElementById("searchinput").value.toString().toLowerCase().trim();
var searchWords = searchinput.split(/\s+/);
var searchColumns = [0,1,2,3,4,5,6,7];
// and or
var resultsArray = data.filter(function(r){
return searchWords.every(function(word){
return searchColumns.some(function(colIndex){
return r[colIndex].toString().toLowerCase().indexOf(word) !== -1
});
});
});
var searchResultsBox = document.getElementById("searchResults");
var templateBox = document.getElementById("rowTemplate");
var template = templateBox.content;
searchResultsBox.innerHTML = "";
resultsArray.forEach(function(r){
var tr = template.cloneNode(true);
var hinmokuColumn = tr.querySelector(".hinmoku");
var buhinCodeuColumn = tr.querySelector(".buhinCode");
var buhinNameColumn = tr.querySelector(".buhinName");
var hitsuyoColumn = tr.querySelector(".hitsuyo");
var genkaColumn = tr.querySelector(".genka");
var kobaiColumn = tr.querySelector(".kobai");
var sagakuColumn = tr.querySelector(".sagaku");
var kenshoColumn = tr.querySelector(".kensho");
hinmokuColumn.textContent = r[0];
buhinCodeuColumn.textContent = r[1];
buhinNameColumn.textContent = r[2];
hitsuyoColumn.textContent = r[3];
genkaColumn.textContent = r[4];
kobaiColumn.textContent = r[5];
sagakuColumn.textContent = r[6];
kenshoColumn.textContent = r[7];
searchResultsBox.appendChild(tr);
});
}
function loadSearchView(){
loadView({func:"loadSearchView", callback: setDataForSearch});
}
window.addEventListener("load", loadSearchView);
function inputEventHandler(e){
if (e.target.matches("#searchinput")){
search();
}
}
document.getElementById("app").addEventListener("input",inputEventHandler);
document.getElementById("app").addEventListener("click",inputEventHandler);
</script>
</body>
</html>
server-side code
function getDataForSearch(){
const ss = SpreadsheetApp.getActiveSpreadsheet();
const ws = ss.getSheetByName("TableData");
return ws.getRange(2, 1, ws.getLastRow(),8).getValues();
}
I need to know what modification needs to be done in the code?
I tried document.getElementById("app").addEventListener("load",inputEventHandler);
but it didn't work.
is there any other event listeners available that will load the search results (or data) (without taking any action on the site, i mean without clicking or typing in the search box)?
Thanks in advance.
Edit: loadsearchview function file code
function loadSearchView(){
return loadPartialHTML_("search");
}
You could use addEventListener with DOMContentLoaded to call a function when all the HTML is loaded and the DOM tree is built. For your particular situation, here's how I managed:
First I need to load data into data variable and call the loadSearchView() function when the page loads:
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", function () {
google.script.run.withSuccessHandler(function (r) {
data = r;
loadSearchView();
}).getDataForSearch();
});
} else {
google.script.run.withSuccessHandler(function (r) {
data = r;
loadSearchView();
}).getDataForSearch();
}
Then I need to load the search view, but instead of calling setDataForSearch, I implemented another function to call functions after this view is loaded. This might be useful if you want to call more than one function after the searchView loads. So basically the code would be like this:
function loadSearchView() {
loadView({ func: "loadSearchView", callback: afterSearchViewLoads });
}
function afterSearchViewLoads(){
loadDataWhenPageLoads();
}
function loadDataWhenPageLoads(){
var resultArray = data;
var searchResultsBox = document.getElementById("searchResults");
var templateBox = document.getElementById("rowTemplate");
var template = templateBox.content;
searchResultsBox.innerHTML = "";
resultsArray.forEach(function (r) {
var tr = template.cloneNode(true);
var hinmokuColumn = tr.querySelector(".hinmoku");
var buhinCodeuColumn = tr.querySelector(".buhinCode");
var buhinNameColumn = tr.querySelector(".buhinName");
var hitsuyoColumn = tr.querySelector(".hitsuyo");
var genkaColumn = tr.querySelector(".genka");
var kobaiColumn = tr.querySelector(".kobai");
var sagakuColumn = tr.querySelector(".sagaku");
var kenshoColumn = tr.querySelector(".kensho");
hinmokuColumn.textContent = r[0];
buhinCodeuColumn.textContent = r[1];
buhinNameColumn.textContent = r[2];
hitsuyoColumn.textContent = r[3];
genkaColumn.textContent = r[4];
kobaiColumn.textContent = r[5];
sagakuColumn.textContent = r[6];
kenshoColumn.textContent = r[7];
searchResultsBox.appendChild(tr);
});
}
Hope this can solve your problem!
AddEventListener when you click enter key in keyboard will help you. Link: EventListener Enter Key
Also addEventListener "change" will help you.
edit
If you want your data to load when page is loaded use one of those ways:
window.onload = function() {
Search();
} // way one
window.onload = Search(); //way two
<body onclick="Search()"> // way three
As you might know from my previous posts, I am developing a chrome extension. I have a button that toggles the extension on & off, and this button's state is saved when you click out of the extension. You can see the code for this below:
popup.html
<!DOCTYPE html>
<html>
<head>
<link rel="StyleSheet" type="text/css" href="style_popup.css"/>
<script type="text/javascript" src="popup.js"></script>
</head>
<body>
<div class="navbar">
View My Dashboard
</div>
<h1 class="center">[Title]</h1>
<button id="buttonclick" class="button">Enable Control</button>
<br> <img src="green_circle.PNG" height="140" width="150" id="centerimage"> <br>
<p class="center" id="status"> [Title] is running! </p>
</body>
</html>
popup.js
let changeColor = document.getElementById('changeColor');
chrome.storage.sync.get('color', function(data) {
changeColor.style.backgroundColor = data.color;
changeColor.setAttribute('value', data.color);
});
document.addEventListener('DOMContentLoaded', function() {
var link = document.getElementById('buttonclick');
// onClick's logic below:
link.addEventListener('click', function() {
handler();
});
});
function handler()
{
chrome.storage.local.get({count: 0}, function (result) {
var count = result.count;
var buttonState = document.getElementById('buttonclick');
var imageState = document.getElementById('centerimage');
var status = document.getElementById('status');
if (count == 0) {
buttonState.style.backgroundColor = "#75ad0a";
buttonState.innerHTML = "Enabled";
imageState.src = "green_circle.PNG";
status.innerHTML = "[Title] is running!"
count = 1;
}
else {
buttonState.style.backgroundColor = "#AA2B0E";
buttonState.innerHTML = "Disabled";
imageState.src = "red_circle.png";
status.innerHTML = "[Title] is not running!"
count = 0;
}
chrome.storage.local.set({count: count});
});
}
However, I am running into a bit of a pickle. I want to make it such that if a user were to click the button (thereby disabling the extension), exit the chrome extension, and then click back into it, it would still show as disabled. With my current case, however, it will just display the "Enable Control" and "[Title] is running" every time they open the extension UNTIL the user clicks the button. In other words, it would be reset & and I want the state to be preserved. As you can see from my popup.js, I've already written code that saves the state of a variable, but I am unsure how to actually make the state be preserved in the HTML. I would greatly appreciate any help, thanks!
I made a chrome extension where my popup button calls a script. The other script uses jQuery but I get an error saying jQuery is not defined.
My popup.html:
<!DOCTYPE html>
<html>
<head>
<title>HomAttendance</title>
</head>
<body>
<h1 style="color:#E54E4E">Hom<span style="color:#4E97E5">Attendance</span></h1>
<button type id="record" style="background-color:White"><h1 style="color:Black">Record Attendance</h1></button>
</body>
<script src="jquery-3.4.1.min.js"></script>
<script src="popup.js"></script>
</html>
My popup.js:
document.addEventListener('DOMContentLoaded', function() {
var login = document.getElementById('record');
login.addEventListener('click', function() {
chrome.tabs.executeScript({file: 'markStudents.js'});
});
});
myScript.js:
var arrays = []
$.get('Attendance.txt', function(data){
var splitted = data.split("\n"); // --> should return an array for each line
// Loop through all lines
for(var i = 0; i < splitted.length; i++)
{
var line = splitted[i];
// Now you could remove [ and ] from string
var removed = line.replace('[','').replace(']','');
var refined = removed.replace(' ', '');
// Now you can split all values by using , delimiter
var values = refined.split(',');
var array = [];
// Now you can iterate through all values and add them to your array
for(var c = 0; c < values.length; c++)
{
var value = values[c];
array.push(value);
}
arrays.push(array);
}
});
var present = arrays[0];
console.log(present);
var absent = arrays[1];
console.log(absent);
var user = present[0];
var pass = absent[0];
var loginField = document.getElementById('fieldAccount');
var passwordField = document.getElementById('fieldPassword');
loginField.value = user;
passwordField.value = pass;
var loginForm = document.getElementById('btn-enter-sign-in');
Is there any way to include my jquery.js in myScript.js?
Console Error
Just import jquery before you import popup.js
Like this
<!DOCTYPE html>
<html>
<head>
<title>HomAttendance</title>
</head>
<body>
<h1 style="color:#E54E4E">Hom<span style="color:#4E97E5">Attendance</span></h1>
<button type id="record" style="background-color:White"><h1 style="color:Black">Record Attendance</h1></button>
</body>
<script src="jquery-3.4.1.min.js"></script>
<script src="popup.js"></script>
</html>
Inside Your popup.js, when you load markStudents.js which uses jQuery, you'd again have to load jQuery before same
Like this
document.addEventListener('DOMContentLoaded', function () {
var login = document.getElementById('record');
login.addEventListener('click', function () {
chrome.tabs.executeScript(null, { file: "jquery-3.4.1.min.js" }, function () {
chrome.tabs.executeScript(null, { file: "markStudents.js" });
});
});
});
Just reorder your script tags and put jQuery before your popup.js. That way it will be loaded when you try to call it.
yo can use this code to include another jquery file in your jquery:
$.getScript("file address");
like this:
$.getScript("/assets/pages/scripts/ui-blockui.min.js");
I am working on the tablet's display of a Pepper robot; I have a functional HTML index page comprising a list of questions—each question redirects to its respective HTML when clicked on—, 2 volume buttons and 2 other buttons—one that pops up an instruction image and the other one that closes the index page and gets back to the splash screen, which when clicked upon, reveals the index page. So far everything is working. The issue is that when I click a question—I get redirected to its HTML page, but then I get stuck there, as neither the 2 volume buttons nor the 2 other buttons work;
I made sure to include the following in each HTML page:
<script type="text/javascript" src="/libs/qimessaging/2/qimessaging.js"></script>
<script type="text/javascript" src="faq.js"></script>
I also reused the same JavaScript functions that worked for the index page.
I commented out some line:
btnPrevious.addEventListener('click', goToPreviousPage);
because I noticed it prevented the splash screen from disappearing when clicked on—i.e., the visibility attribute stays on visible instead of switching to hidden thus revealing the index page, but still, the 3 remaining buttons don't work anyway.
Here is my faq.js code:
/* global QiSession */
var serviceName = 'ADFAQ';
var volumeUpEvent = serviceName + '/VolumeUp';
var volumeDownEvent = serviceName + '/VolumeDown';
var volumeData = serviceName + '/Volume';
/* Clickable buttons */
var btnReturn = document.getElementById('return');
var btnHelp = document.getElementById('call_help');
var btnPrevious = document.getElementById('previous_page');
var btnVolUp = document.getElementById('volume-up');
var btnVolDown = document.getElementById('volume-down');
/* Help image and splash screen */
var helper = document.getElementById('helper');
var img = document.getElementById('click_on_me');
var memory;
var volume;
var audioDevice;
QiSession(connected, disconnected);
function connected (s) {
console.log('QiSession connected');
var questions = document.getElementById('questions');
/* Associating buttons to their respective functions */
btnHelp.addEventListener('click', showHelper);
btnReturn.addEventListener('click', closeQuestions);
//btnPrevious.addEventListener('click', goToPreviousPage);
btnVolUp.addEventListener('click', raiseVolume);
btnVolDown.addEventListener('click', lowerVolume);
img.addEventListener('click', loadQuestions);
questions.addEventListener('click', clickOnQuestion);
s.service('ALMemory').then(function (m) {
m.subscriber(serviceName + '/DialogEnded').then(function (subscriber) {
subscriber.signal.connect(hideQuestions);
});
m.subscriber(serviceName + '/Pepper').then(function (subscriber) {
subscriber.signal.connect(displayPepperHTML)
});
m.subscriber(serviceName + '/RaiseVolume').then(function (subscriber) {
subscriber.signal.connect(raiseVolume);
});
m.subscriber(serviceName + '/LowerVolume').then(function (subscriber) {
subscriber.signal.connect(lowerVolume);
});
memory = m;
});
s.service('ALAudioDevice').then(function (a) {
a.getOutputVolume().then(assignVolume);
audioDevice = a
});
}
function disconnected () {
console.log('QiSession disconnected');
}
function assignVolume(value){
volume = value;
}
function raiseVolume (event) {
var changed = 0;
if(volume < 100) {
volume = Math.min(volume + 5, 100);
audioDevice.setOutputVolume(volume);
changed = 1;
}
memory.insertData(volumeData, volume);
memory.raiseEvent(volumeUpEvent, changed);
}
function lowerVolume (event) {
var changed = 0;
if(volume > 30) {
volume = Math.max(volume - 5, 0);
audioDevice.setOutputVolume(volume);
changed = 1;
}
memory.insertData(volumeData, volume);
memory.raiseEvent(volumeDownEvent, changed);
}
function showHelper (event) {
if (btnHelp.innerHTML === '?') {
helper.style.opacity = '1';
helper.style.zIndex = '1';
btnHelp.innerHTML = '←';
} else {
helper.style.opacity = '0';
helper.style.zIndex = '-1';
btnHelp.innerHTML = '?';
}
btnHelp.blur();
}
function loadQuestions (event) {
memory.raiseEvent(serviceName + '/LoadQuestions', 1);
img.style.visibility = 'hidden';
}
function goToPreviousPage () {
window.location.href = "index.html";
}
function displayPepperHTML() {
window.location.href = "pepper.html";
}
function closeQuestions (event) {
if(location.href != "index.html")
{window.location.href = "index.html";}
memory.raiseEvent(serviceName + '/CloseQuestions', 1);
btnReturn.blur();
}
function hideQuestions (data) {
if (data !== 0) {
img.style.visibility = 'visible';
helper.style.opacity = '0';
btnHelp.innerHTML = '?';
}
}
function clickOnQuestion (event) {
memory.raiseEvent(serviceName + '/' + event.target.id, 1);
}
Here is my non-functioning pepper.html code:
<!DOCTYPE html>
<html lang="fr">
<head>
<title>Pepper</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=1280, user-scalable=no" />
<link type="text/css" rel="stylesheet" href="css/style.css" />
<link type="text/css" rel="stylesheet" href="css/faq.css" />
</head>
<body>
<header>
<h1>Bla bla bla</h1>
<span class="buttons">
<button id="previous_page" class="button-help"> ← </button>
<button id="return" class="button-return">X</button>
</span>
<div id="helper" class="pop-up">
<img src="img/interactionscreen_frf.png" alt="Bla bla bla">
</div>
</header>
<ul id="questions">
<p>
Bla bla bla
</p>
<div class="volume-part">
<div id="volume-up" class="Click-me">+</div>
<img src="img/speaker.png" alt="Bla bla bla" style="vertical-align: middle;">
<div id="volume-down" class="Click-me">-</div>
</div>
</ul>
<script type="text/javascript" src="/libs/qimessaging/2/qimessaging.js"></script>
<script type="text/javascript" src="faq.js"></script>
</body>
</html>
Thank you for your help.
I am expecting the pepper.html page to respond to both the volume and ← and X buttons, as the index.html should, since they use the exact same Javascript.
I was able to find some workaround: creating one JavaScript file for each HTML page, this is redundant and non-optimal I know, but at least it works.
This also made me realize that the commented-out line was blocking the program because the index.html page doesn't use the previous_page button, that's what led me to make a JS file for each HTML page.
If anybody has any other suggestions I am all ears.
Edit: I reduced the number of JS scripts to only 2. One for the index.html and the other for the identically-structured html pages of the other questions.
So this code selects random image whenever a person loads my website, how can I change the code so that images are selected sequentially from first to last everytime a person loads the website and then again resets to first image when the counter reaches the end?
P.s- The code works fine on hosting server, here it gives an error i don't know why.
window.onload = choosePic;
var myPix = new Array("https://i.imgur.com/LHtVLbh.jpg", "https://i.imgur.com/2YHazkp.png", "https://i.imgur.com/Uscmgqx.jpg");
function choosePic() {
var randomNum = Math.floor(Math.random() * myPix.length);
document.getElementById("myPicture").src = myPix[randomNum];
}
<!DOCTYPE html>
<html>
<head>
<title>Random Image</title>
<script src="thumb.js"></script>
</head>
<body>
<img src="images/spacer.gif" id="myPicture" alt="some image">
</body>
</html>
You can use localstorage to achieve this. When the user enters the website, you can do something like:
var pictureIndex = localstorage.getItem("pictureIndex");
But since it may be the user's first visit, it would be better to have:
var pictureIndex = localstorage.getItem("pictureIndex") || 0;
Then, you just increment the pictureIndex and perform a modulo operation (for the case when this is the last image)
pictureIndex = (pictureIndex + 1) % myPix.length;
To save this index, you can use
localStorage.setItem('pictureIndex', pictureIndex);
Next time when the user refreshes the page (or comes back), he will get the next picture in your array.
The final code should look like this:
window.onload = choosePic;
var myPix = new Array("https://i.imgur.com/LHtVLbh.jpg", "https://i.imgur.com/2YHazkp.png", "https://i.imgur.com/Uscmgqx.jpg");
function choosePic() {
var pictureIndex = window.localStorage.getItem("pictureIndex") || 0;
pictureIndex = (pictureIndex + 1) % myPix.length;
window.localStorage.setItem("pictureIndex", pictureIndex);
document.getElementById("imgid").innerHTML = pictureIndex;
document.getElementById("myPicture").src = myPix[pictureIndex];
}
<!DOCTYPE html>
<html>
<head>
<title>Random Image</title>
<script src="thumb.js"></script>
</head>
<body>
Press "Run" multiple times to cycle through the images.
Currently showing: <span id="imgid"></span>
<img src="images/spacer.gif" id="myPicture" alt="some image">
</body>
</html>
Note that the above code might not work here (but you can test it locally) due to some security restrictions from jsfiddle. A working version can be accessed >here<
function choosePic() {
var local_item = 0;
if(localStorage.getItem('pic_key')){
local_item = parseInt(intvlocalStorage.getItem('pic_key'));
}
if(local_item >= myPix.length){
local_item = 0;
}
localStorage.setItem('pic_key', local_item + 1);
document.getElementById("myPicture").src = myPix[local_item];
}
You can use LocalStorage to achieve this. When the user enters the website, you can store the key and increment it.
Use local storage to save the data you need [e.g. visited = 3(3rd time the same person visited your website)]
Your js code can be implemented like this:
window.onload = choosePic;
var myPix = new Array("https://i.imgur.com/LHtVLbh.jpg", "https://i.imgur.com/2YHazkp.png", "https://i.imgur.com/Uscmgqx.jpg");
function choosePic() {
if (localStorage.getItem('visited') == null)
{
document.getElementById("myPicture").src = myPix[0];
localStorage.setItem('visited', 1);
}
else if (localStorage.getItem('visited') >= myPix.length)
{
localStorage.setItem('visited', 0);
document.getElementById("myPicture").src = myPix[localStorage.getItem('visited')];
}
else
{
document.getElementById("myPicture").src = myPix[localStorage.getItem('visited')];
localStorage.setItem('visited', localStorage.getItem('visited') + 1);
}
}