Toggle function vanilla javascript - javascript

I would like to toggle between degree's and fahrenheit when the temperature is clicked.
I have managed to do this when it is clicked on degree's it is changed to fahrenheit, but now how do i change it back to degree's when clicked on fahrenheit?
temp.addEventListener('click', degreeToF);
function degreeToF() {
const f = manchester.current.temp_c * 1.8 + 32;
temp.innerHTML = f.toFixed(0) + '<span class="degrees"> f </span>';
}
Here is my codepen: https://codepen.io/o-sewell/pen/mRyEyW

var showing = 'F';
temp.addEventListener('click', degreeToF);
function degreeToF() {
if(showing === 'F'){
// convert to C
showing = 'C';
const f = (manchester.current.temp_c - 32 ) * 5/9;
temp.innerHTML = f.toFixed(0) + '<span class="degrees"> c </span>';
} else {
// convert to
showing = 'F';
const f = manchester.current.temp_c * 1.8 + 32;
temp.innerHTML = f.toFixed(0) + '<span class="degrees"> f </span>';
}
}

Here you go. Used simple boolean value to tell the function which part of code to execute.
CodePen link
const weather = 'https://api.apixu.com/v1/current.json?key=cd93499e97644fcc873154715163112&q=Manchester';
const baseColors = ["#C2272D", "#F8931F", "#FFFF01", "#009245", "#0193D9", "#0C04ED", "#612F90"];
const tintColors = ["#F8DDDE", "#FEDBB4", "white", "#0193D9", "#009245", "#E7E6F9"];
let manchester = [];
fetch(weather)
.then((blob) => blob.json())
.then((data) => manchester = data)
.then((data) => displayWeather(data));
let iconWeather = document.querySelector('#weather');
let temp = document.querySelector('#temp');
let textLocation = document.querySelector('#text-location');
let textWeather = document.querySelector('#text-weather');
function displayWeather() {
iconWeather.src = manchester.current.condition.icon;
temp.innerHTML = manchester.current.temp_c + '<span class="degrees"> c </span>';
textLocation.innerHTML = manchester.location.name;
textWeather.innerHTML = manchester.current.condition.text;
};
const background = document.querySelector('.weather');
window.addEventListener('load', changeBackground);
function changeBackground() {
let random = Math.floor(Math.random() * baseColors.length);
let randomBaseColor = baseColors[random];
let randomTintColor = tintColors[random];
background.style.background = 'linear-gradient(0deg,' + randomBaseColor + ',' + randomTintColor + ')';
background.style.transition = 'background , 2s, ease';
}
setInterval(changeBackground, 2500);
temp.addEventListener('click', degreeToF);
var x = true;
function degreeToF() {
if (x) {
const f = manchester.current.temp_c * 1.8 + 32;
temp.innerHTML = f.toFixed(0) + '<span class="degrees"> f </span>';
x = !x;
} else {
const f = manchester.current.temp_c;
temp.innerHTML = f.toFixed(0) + '<span class="degrees"> c </span>';
x = !x;
}
}
* {
box-sizing: border-box;
}
.wrapper {
margin: 50px;
}
.weather {
max-width: 90%;
margin: 0 auto;
background: pink;
padding: 20px;
box-shadow: 0 5px rgba(0, 0, 0, 0.1);
border-radius: 6px;
}
#media (min-width: 800px) {
.weather {
max-width: 40%;
}
}
.weather__temperature {
margin-top: 50px;
text-align: center;
}
.weather__temperature--temp {
font-size: 80px;
cursor: pointer;
}
.weather__text {
text-align: center;
}
.weather__text--description {
color: black;
font-size: 18px;
}
.weather__icon {
margin-top: 5px;
}
.weather__icon--image {
display: block;
margin: 0 auto;
padding: 5px 0;
width: 150px;
height: auto;
}
.weather__location {
text-align: center;
}
.weather__location--text {
letter-spacing: 5px;
font-size: 22px;
margin-bottom: 50px;
}
.degrees {
color: red;
font-size: 20px;
}
<div class="wrapper">
<div class="weather">
<div class="weather__temperature" />
<p class="weather__temperature weather__temperature--temp" id="temp"></p>
</div>
<div class="weather__text">
<p class="weather__text weather__text--description" id="text-weather"></p>
</div>
<div class="weather__icon">
<img class="weather__icon weather__icon--image" id="weather" src="" />
</div>
<div class="weather__location">
<p class="weather__location--text" id="text-location"></p>
</div>
</div>
</div>

Related

Creating a number guessing game that has stages

Create a number guessing game to generate a number between the range of 1 and 2. The game should prompt users for their username.
Set range as function parameter and prompt the player to predict the generated number between the given range. At a correct guess, the game should award the player a point and move them to stage 2 by increasing the range limit value by 1, e.g. range is from 1 and 3 for stage 2 and so on.
I created it but to flow from one level to another is the problem
This is a working solution. Feel free to comment with any questions.
let rangeTracker = [1, 2]
let totalPointsTracker = [0]
function randomIntFromInterval(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min)
}
document.getElementById('continueBtn').onclick = function() {
let username = document.getElementById("newUsername").value
if (username != '') {
document.querySelector('.usernameCon').style.display = 'none'
document.querySelector('.userInfo').style.display = 'flex'
document.querySelector('.gameCon').style.display = 'flex'
document.getElementById("username").innerHTML = `Hello ${username}, this is stage ${totalPointsTracker[0] + 1}`
document.getElementById("totalPoints").innerHTML = `Total Points: ${totalPointsTracker[0]}`
document.getElementById("title").innerHTML = `Guess a number between ${rangeTracker[0]} and ${rangeTracker[1]}`
}
}
const randomInt = randomIntFromInterval(rangeTracker[0], rangeTracker[1])
document.getElementById('guessBtn').onclick = function() {
let userGuess = document.getElementById("userGuess").value
if (userGuess != '') {
if (userGuess == randomInt) {
document.getElementById("status").innerHTML = `Correct!`
document.getElementById("status").style.color = 'forestgreen'
const previousMaxRange = rangeTracker[1]
rangeTracker[1] = previousMaxRange + 1
const previousTotalPoints = totalPointsTracker[0]
totalPointsTracker[0] = previousTotalPoints + 1
success()
} else {
document.getElementById("userGuess").value = ''
document.getElementById("status").innerHTML = `Incorrect, guess again!`
document.getElementById("status").style.color = 'red'
}
} else if (userGuess == '') {
document.getElementById("status").innerHTML = `Please guess a number!`
document.getElementById("status").style.color = 'red'
}
}
function success() {
let username = document.getElementById("newUsername").value
document.getElementById("userGuess").value = ''
document.getElementById("username").innerHTML = `Hello ${username}, this is stage ${totalPointsTracker[0] + 1}`
document.getElementById("totalPoints").innerHTML = `Total Points: ${totalPointsTracker[0]}`
document.getElementById("title").innerHTML = `Guess a number between ${rangeTracker[0]} and ${rangeTracker[1]}`
}
.usernameCon {
display: flex;
flex-direction: column;
}
.usernameCon label {
font-size: 26px;
}
.usernameCon #newUsername {
width: 230px;
margin-top: 10px;
}
.usernameCon #continueBtn {
font-size: 17px;
width: 130px;
margin-top: 10px;
cursor: pointer;
}
.userInfo {
display: none;
flex-direction: column;
height: fit-content;
}
.userInfo #username {
font-size: 26px;
}
.userInfo #totalPoints {
font-size: 24px;
margin-top: 10px;
}
.gameCon {
display: none;
flex-direction: column;
}
.gameCon #title {
font-size: 22px;
margin-top: 10px;
}
.gameCon #status {
font-size: 20px;
margin-top: 10px;
}
.gameCon #userGuess {
width: 230px;
margin-top: 8px;
}
.gameCon #guessBtn {
font-size: 17px;
width: 130px;
margin-top: 10px;
cursor: pointer;
}
<div class="usernameCon">
<label>Enter Your Username</label>
<input id="newUsername" />
<button id="continueBtn">Continue</buttom>
</div>
<div class="userInfo">
<label id="username"></label>
<label id="totalPoints"></label>
</div>
<div class="gameCon">
<label id="title">Guess a number between 1 and 2</label>
<label id="status"></label>
<input id="userGuess" />
<button id="guessBtn">Guess</button>
</div>

Add editable drop-down with multi select items through html css or vanilla js

Just wanted to know easiest way to achieve this
Perhaps something like this:
(()=>
{
const formEls = document.querySelectorAll(".input-tags");
for(let i = 0; i < formEls.length; i++)
{
const formEl = formEls[i],
inputEl = document.createElement("input"),
tagsEl = document.createElement("span"),
listEl = document.createElement("datalist");
formEl.tags = [];
Object.defineProperties(formEl, {
list: {
get(){return getData(this, "list")},
set(val){this.dataset.list = val}
},
tags: {
get(){return getData(this, "tags")},
set(val){this.dataset.tags = val}
},
value:
{
get(){return this.dataset.value || ""},
set(val){this.dataset.value = val}
}
});
const list = formEl.list;
listEl.id = "input-tags-datalist" + i;
inputEl.setAttribute("list", listEl.id);
inputEl.type = "text";
tagsEl.className = "tags";
for(let i = 0, optionEl = document.createElement("option"); i < list.length; i++)
{
optionEl = optionEl.cloneNode(false);
optionEl.value = list[i];
listEl.appendChild(optionEl);
}
formEl.appendChild(tagsEl);
formEl.appendChild(inputEl);
formEl.appendChild(listEl);
inputEl._isClicked = true;
inputEl.addEventListener("keydown", e => inputEl._isClicked = !e.keyCode || e.keyCode==13);
inputEl.addEventListener("keyup", e => inputEl._isClicked = true);
inputEl.addEventListener("input", e =>
{
formEl.value = inputEl.value;
if (!inputEl._isClicked && !inputEl.value.match(/(^[^"']+ $)|(^(["']).+\3$)/))
{
dispatchEvent(formEl, "input");
return inputWidth(formEl);
}
const val = inputEl.value.replace(/^\s*((["'])([^"']+)\2|([^"']+)\s+)$/, "$4$3").replace(/[^\w -_]+/g, "").replace(/[ ]{2,}/g, " ");
if (formEl.dataset.autotags !== undefined || formEl.list.indexOf(val) != -1)
{
inputEl.value = val;
addTag(inputEl);
}
formEl.value = inputEl.value;
dispatchEvent(formEl, "input");
inputWidth(formEl);
});//inputEl.oninput()
tagsEl.addEventListener("click", e =>
{
if (!e.target.parentNode.classList.contains("tag"))
return;
const tag = e.target.parentNode.textContent,
list = formEl.list,
tags = formEl.tags,
index = list.indexOf(tag),
optionEl = listEl.children[index];
if (optionEl.classList.contains("new"))
{
list.splice(index, 1);
optionEl.parentNode.removeChild(optionEl);
}
else
optionEl.disabled = false;
tags.splice(tags.indexOf(tag), 1);
formEl.tags = tags;
formEl.list = list;
e.target.parentNode.parentNode.removeChild(e.target.parentNode);
inputWidth(formEl);
e.stopPropagation();
formEl.click();
dispatchEvent(formEl, "input");
});//tagsEl.onclick()
formEl.addEventListener("click", e => inputEl.focus());
inputWidth(formEl);
}
function dispatchEvent(el, type, opts)
{
return el.dispatchEvent(new Event(type, opts));
}
function inputWidth(formEl)
{
const inputEl = formEl.querySelector("input");
inputEl.style.width = "1em"; //min width
const inputStyle = window.getComputedStyle(inputEl),
formStyle = window.getComputedStyle(inputEl.parentNode),
inputRect = inputEl.getBoundingClientRect(),
formRect = inputEl.parentNode.getBoundingClientRect(),
canvas = document.createElement('canvas'),
ctx = canvas.getContext("2d");
ctx.font = inputStyle.font;
const widthText = (ctx.measureText(inputEl.value).width
+ parseFloat(inputStyle.paddingLeft)
+ parseFloat(inputStyle.paddingRight)
+ parseFloat(inputStyle.textIndent)
+ parseFloat(inputStyle.borderLeftWidth)
+ parseFloat(inputStyle.borderRightWidth)
+ 1
),
widthBox = formRect.right - inputRect.left - parseFloat(formStyle.paddingLeft) - parseFloat(formStyle.paddingRight) - 1;
inputEl.style.width = Math.max(widthText, widthBox) + "px";
}
function getData(el, key)
{
return el.dataset[key] ? el.dataset[key].split(",") : [];
}
function addTag(input)
{
const formEl = input.parentNode,
tag = input.value.trim(),
list = formEl.list,
tags = formEl.tags;
if (tag === "" || tags.indexOf(tag) != -1)
return;
const tagsEl = formEl.querySelector(".tags"),
tagEl = document.createElement("span"),
datalistEl = formEl.querySelector("datalist");
if (formEl.dataset.autotags !== undefined && list.indexOf(tag) == -1)
{
const option = document.createElement("option");
option.value = tag;
option.className = "new";
datalistEl.appendChild(option);
list[list.length] = tag;
}
tags[tags.length] = tag;
formEl.list = list;
formEl.tags = tags;
const index = list.indexOf(tag);
datalistEl.children[index].disabled = true;
tagEl.className = "tag";
tagEl.textContent = tag;
tagEl.appendChild(document.createElement("span"));
tagsEl.appendChild(tagEl);
input.value = "";
}
})();
//example:
const test = document.getElementById("test");
test.addEventListener("input", e =>
{
if (e.target !== test)
return;
console.log('value:', test.value);
console.log("tags:", JSON.stringify(test.tags));
console.log("list:", JSON.stringify(test.list));
}, false);
.input-tags
{
display: inline-block;
border: 1px solid black;
font-size: 0.8em;
padding: 0.1em 0.1em 0.1em 0.05em;
width: 100%;
line-height: 1em;
}
.input-tags > input,
.input-tags > input:focus,
.input-tags > input:active
{
outline: none;
border: none;
margin: 0.15em 0;
vertical-align: middle;
max-width: 100%;
box-sizing: border-box;
}
.input-tags > input::-webkit-calendar-picker-indicator
{
display: none !important;
}
.input-tags > .tags
{
vertical-align: middle;
}
.input-tags .tags .tag
{
display: inline-block;
background-color: lightblue;
border: 1px solid blue;
border-radius: 2px;
font-family: "Segoe UI","Liberation Sans",sans-serif;
margin: 0.1em;
padding: 0 0.2em;
line-height: 1.3em;
}
.input-tags .tags .tag > span
{
margin: -0.05em -0.2em 0 0.05em;
cursor: pointer;
display: inline-block;
font-size: 1.3em;
transform: rotate(45deg);
border-radius: 2em;
line-height: 0.7em;
float: right;
}
.input-tags .tags .tag > span:before
{
content: "+";
position: relative;
top: -0.1em;
}
.input-tags .tags .tag > span:hover
{
background-color: #60B3CE;
}
<div style="display: grid; grid-template-columns: auto auto">
<span>Auto-add new tags, suggestions:</span>
<div style="display: inline-block; width: 50vw;">
<div id="test" class="input-tags" data-autotags data-list="test,sometag,SOMETAG,another tag,another tag2,another tag3,another,tag"></div>
</div>
<span>Auto-add new tags, no suggestions:</span>
<div style="display: inline-block; width: 50vw;">
<span class="input-tags" data-autotags></span>
</div>
<span>No new tags, suggestions:</span>
<div style="display: inline-block; min-width: 10em;">
<div class="input-tags" data-list="test,some tag,very long tag,blah"></div>
</div>
<div>

How to stop the execution of a function on click

I have this typewriter effect, I also have a website in 3 languages. When changing the language, I want the script to be re-executed with the new language. For this, I added an onclick event. Everything works, but there is a bug, if we change the language during the execution of the script, the new one will be executed on top of the old one. So, how, in my case, can I stop the old script and execute the new one?
I tried to use return as posted in other answers, tried to use clearTimeout but still doesn't work.
The snippet does not work. I am using localStorage and here it looks like it is locked.
UPD. The snippet is already working.
var isTag, text, langText, i = 0;
langText = "Hi!<br>Text,<br>Text ";
(function e() {
if ((text = langText.slice(0, ++i)) !== langText) {
document.querySelector(".index-title-main h1").innerHTML = text;
var t = text.slice(-1);
if ("<" === t && (isTag = !0), ">" === t && (isTag = !1), isTag) return e();
setTimeout(e, 100);
}
}());
document.querySelector('.en').onclick = function() {
var isTag, text, langText, i = 0;
langText = "Hi!<br>Text,<br>Text ";
(function e() {
if ((text = langText.slice(0, ++i)) !== langText) {
document.querySelector(".index-title-main h1").innerHTML = text;
var t = text.slice(-1);
if ("<" === t && (isTag = !0), ">" === t && (isTag = !1), isTag) return e();
setTimeout(e, 100);
}
}());
};
document.querySelector('.de').onclick = function() {
var isTag, text, langText, i = 0;
langText = "Hallo!<br>Text,<br>Text ";
(function e() {
if ((text = langText.slice(0, ++i)) !== langText) {
document.querySelector(".index-title-main h1").innerHTML = text;
var t = text.slice(-1);
if ("<" === t && (isTag = !0), ">" === t && (isTag = !1), isTag) return e();
setTimeout(e, 100);
}
}());
};
document.querySelector('.ru').onclick = function() {
var isTag, text, langText, i = 0;
langText = "Привет!<br>Текст,<br>Текст ";
(function e() {
if ((text = langText.slice(0, ++i)) !== langText) {
document.querySelector(".index-title-main h1").innerHTML = text;
var t = text.slice(-1);
if ("<" === t && (isTag = !0), ">" === t && (isTag = !1), isTag) return e();
setTimeout(e, 100);
}
}());
};
.lang{
display: flex;
}
.lang a{
color: #000;
width: 100px;
display: block;
transition: .5s;
font-weight: bold;
text-align: center;
text-decoration: none;
border: 1px solid #000;
}
.lang a:not(:last-child){
margin-right: 10px;
}
.lang a:hover{
color: #fff;
transition: .5s;
background-color: #000;
}
.index-title-main{
padding-left: 50px;
}
<div class="lang">
<a class="en" href="#">English</a>
<a class="de" href="#">Deutsche</a>
<a class="ru" href="#">Русский</a>
</div>
<div class="index-title-main">
<h1></h1>
</div>
I have refactored your code and moved the common function outside the click event handler.
We need to clear the interval at the start of the function as we can be sure that as the execution has reached here we no longer need any previous running instance of other language click handlers.
var langText, i = 0, timeout;
langText = "Hi!<br>Text,<br>Text ";
function animateText() {
var isTag, text;
timeout && clearTimeout(timeout);
if ((text = langText.slice(0, ++i)) !== langText) {
document.querySelector(".index-title-main h1").innerHTML = text;
var t = text.slice(-1);
if ("<" === t && (isTag = !0), ">" === t && (isTag = !1), isTag) return animateText();
timeout = setTimeout(animateText, 100);
}
};
animateText();
document.querySelector('.en').onclick = function() {
i = 0, langText = "Hi!<br>Text,<br>Text ";
animateText();
};
document.querySelector('.de').onclick = function() {
i = 0, langText = "Hallo!<br>Text,<br>Text ";
animateText();
};
document.querySelector('.ru').onclick = function() {
i = 0, langText = "Привет!<br>Текст,<br>Текст ";
animateText();
};
.lang{
display: flex;
}
.lang a{
color: #000;
width: 100px;
display: block;
transition: .5s;
font-weight: bold;
text-align: center;
text-decoration: none;
border: 1px solid #000;
}
.lang a:not(:last-child){
margin-right: 10px;
}
.lang a:hover{
color: #fff;
transition: .5s;
background-color: #000;
}
.index-title-main{
padding-left: 50px;
}
<div class="lang">
<a class="en" href="#">English</a>
<a class="de" href="#">Deutsche</a>
<a class="ru" href="#">Русский</a>
</div>
<div class="index-title-main">
<h1></h1>
</div>
Here is a DRY version
const langTexts = {
en: "Hi!<br>Text,<br>Text ",
de: "Hallo!<br>Text,<br>Text ",
ru: "Привет!<br>Текст,<br>Текст "
}
let langText = langTexts["en"]; // langText[languageFromLocalStorage || "en"]
let tId, isTag, cnt = 0;
const h1 = document.querySelector(".index-title-main h1");
const typer = () => {
if ((text = langText.slice(0, ++cnt)) !== langText) {
h1.innerHTML = text;
const t = text.slice(-1);
if ("<" === t && (isTag = !0), ">" === t && (isTag = !1), isTag) return typer();
tId = setTimeout(typer, 100);
}
}
document.getElementById("nav").addEventListener("click", e => {
e.preventDefault();
const tgt = e.target;
console.log(tgt.getAttribute("lang"))
cnt = 0;
langText = langTexts[tgt.getAttribute("lang")];
clearTimeout(tId)
tId = setTimeout(typer, 100);
})
typer()
.lang {
display: flex;
}
.lang a {
color: #000;
width: 100px;
display: block;
transition: .5s;
font-weight: bold;
text-align: center;
text-decoration: none;
border: 1px solid #000;
}
.lang a:not(:last-child) {
margin-right: 10px;
}
.lang a:hover {
color: #fff;
transition: .5s;
background-color: #000;
}
.index-title-main {
padding-left: 50px;
}
<div id="nav">
<a class="langLink" href="#" lang="en">English</a>
<a class="langLink" href="#" lang="de">Deutsch</a>
<a class="langLink" href="#" lang="ru">Русский</a>
</div>
<div class="index-title-main">
<h1></h1>
</div>

How to set a function for every element, using forEach in JavaScript?

I'm making an Etch a sketch game in JS.
I have a two questions:
1) How to set a function to all elements in grid?
cellArray.forEach(elem => {
elem.addEventListener('mouseover', () => {
elem.style.backgroundColor = 'red';
});
});
When i change color like that, it's changing for all cells, but when i try with function it's change only the last one, when i mouseover of any of it.
2) How can i do my grid change size every time when the input.value changed by user, without reloading the page? I think about AJAX, but i'm very new one, so i don't know much.
let sketch = document.querySelector('#sketch-grid'),
cellArray = [],
input = document.querySelector('.input-skh'),
cellNumber;
cellNumber = input.value;
let colors = {
blue: function () {
cell.style.backgroundColor = 'blue';
},
white: function () {
cell.style.backgroundColor = 'white';
},
random: function () {
let r = Math.floor(Math.random() * (256)),
g = Math.floor(Math.random() * (256)),
b = Math.floor(Math.random() * (256)),
randomColor = '#' + r.toString(16) + g.toString(16) + b.toString(16);
cell.style.backgroundColor = randomColor;
}
};
function buildGrid(){
sketch.style.gridTemplateRows = `repeat(${cellNumber}, auto)`;
sketch.style.gridTemplateColumns = `repeat(${cellNumber}, auto)`;
for (let i = 0; i < cellNumber * cellNumber; i++){
cell = document.createElement('div');
cell.classList.add('cell');
sketch.appendChild(cell);
cellArray.push(cell);
}
}
input.addEventListener('oninput', buildGrid());
/*let cellNumber = +prompt('The size of sketch is: ');*/
function changeColor(){
colors.random();
}
cellArray.forEach(elem => elem.addEventListener('mouseover', changeColor()));
* {
box-sizing: border-box;
}
.sketch-input {
margin: auto;
text-align: center;
background-color: lightseagreen;
}
.sketch-input .input-skh {
width: 300px;
height: 70px;
background-color: mediumpurple;
font-size: 40px;
color: white;
}
.sketch-input label {
color: white;
font-size: 35px;
}
.wrapper-sketch {
width: 100%;
height: 800px;
background-color: black;
padding: 20px;
}
.wrapper-sketch #sketch-grid {
display: grid;
margin: 10px auto;
width: 500px;
height: 500px;
}
.wrapper-sketch #sketch-grid div {
border: 2px solid crimson;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Etch a sketch</title>
<link rel="stylesheet" href="../templates/main.css">
</head>
<body>
<div class="sketch-input">
<label>Choose a size of your sketch:</label>
<input class="input-skh" type="range" min="3" max="50">
</div>
<div class="wrapper-sketch">
<div id="sketch-grid"></div>
</div>
<div class="buttons">
<button class="button__choose-color">Change Color</button>
<button class="button__reset">RESET</button>
</div>
<script src="../js/app.js"></script>
</body>
</html>
Checkout the fixes in snippet below:
Minor changes:
cellArray.forEach(elem => elem.addEventListener('mouseover', () => changeColor(elem)));
Register the event handler function instead of calling changeColor() function immediately. Also pass in the current elem to the function.
random: function (elem) {
let r = Math.floor(Math.random() * (256)),
g = Math.floor(Math.random() * (256)),
b = Math.floor(Math.random() * (256)),
randomColor = '#' + r.toString(16) + g.toString(16) + b.toString(16);
elem.style.backgroundColor = randomColor;
}
Use the elem as the argument/parameter instead of using global cell value.
Expand and see snippet below:
let sketch = document.querySelector('#sketch-grid'),
cellArray = [],
input = document.querySelector('.input-skh'),
cellNumber;
cellNumber = input.value;
let colors = {
blue: function () {
cell.style.backgroundColor = 'blue';
},
white: function () {
cell.style.backgroundColor = 'white';
},
random: function (elem) {
let r = Math.floor(Math.random() * (256)),
g = Math.floor(Math.random() * (256)),
b = Math.floor(Math.random() * (256)),
randomColor = '#' + r.toString(16) + g.toString(16) + b.toString(16);
elem.style.backgroundColor = randomColor;
}
};
function buildGrid(){
sketch.style.gridTemplateRows = `repeat(${cellNumber}, auto)`;
sketch.style.gridTemplateColumns = `repeat(${cellNumber}, auto)`;
for (let i = 0; i < cellNumber * cellNumber; i++){
cell = document.createElement('div');
cell.classList.add('cell');
sketch.appendChild(cell);
cellArray.push(cell);
}
}
input.addEventListener('oninput', buildGrid());
/*let cellNumber = +prompt('The size of sketch is: ');*/
function changeColor(elem){
colors.random(elem);
}
cellArray.forEach(elem => elem.addEventListener('mouseover', () => changeColor(elem)));
* {
box-sizing: border-box;
}
.sketch-input {
margin: auto;
text-align: center;
background-color: lightseagreen;
}
.sketch-input .input-skh {
width: 300px;
height: 70px;
background-color: mediumpurple;
font-size: 40px;
color: white;
}
.sketch-input label {
color: white;
font-size: 35px;
}
.wrapper-sketch {
width: 100%;
height: 800px;
background-color: black;
padding: 20px;
}
.wrapper-sketch #sketch-grid {
display: grid;
margin: 10px auto;
width: 500px;
height: 500px;
}
.wrapper-sketch #sketch-grid div {
border: 2px solid crimson;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Etch a sketch</title>
<link rel="stylesheet" href="../templates/main.css">
</head>
<body>
<div class="sketch-input">
<label>Choose a size of your sketch:</label>
<input class="input-skh" type="range" min="3" max="50">
</div>
<div class="wrapper-sketch">
<div id="sketch-grid"></div>
</div>
<div class="buttons">
<button class="button__choose-color">Change Color</button>
<button class="button__reset">RESET</button>
</div>
<script src="../js/app.js"></script>
</body>
</html>

Array wont update when i JSON.stringify it

I have this code below that is able to transfer the array value to another array when i click on it. For Example, when i click on lime it will move into my Green Array The problem is after i JSON.stringify my Green Array it doesn't show the updated value.
So this is the before i add in a value my green array has 5 values.
And this is after I add in a value to my green array as you can see after I move the value in my array count increases but I don't know why when i stringify the array, it doesn't have the value I added in already I want to stringify it because I want to send the updated data to a server. Is there any reason why this is happening ?
var red = {};
var green = {};
var random = {};
var fruits = [];
var fruits1 = {["fruit"]:"Apple", ["type"]:"1"}
var fruits2 = {["fruit"]:"Tomato", ["type"]:"1"}
var fruits3 = {["fruit"]:"Lime", ["type"]:"2"}
var fruits4 = {["fruit"]:"Guava", ["type"]:"2"}
fruits.push(fruits1,fruits2,fruits3,fruits4);
var randomFruits = fruits.filter(x => x.fruit).map(x => x.fruit);
var key = "Red Fruits";
red[key] = ['Apple', 'Cherry', 'Strawberry','Pomegranate','Rassberry'];
var key2 = "Green Fruits";
green[key2] = ['Watermelon', 'Durian', 'Avacado','Lime','Honeydew'];
var key3 = "Random Fruits";
random[key3] = randomFruits;
function redraw() {
var combineString = '';
$.each(red[key], function(index) {
combineString += ('<div class="pilldiv redpill class">' + red[key][index] + '</div>');
});
$('.combineclass').html(combineString);
$.each(green[key2], function(index) {
combineString += ('<div class="pilldiv greenpill class">' + green[key2][index] + '</div>');
});
$('.combineclass').html(combineString);
var randomString = '';
$.each(random[key3], function(index) {
randomString += ('<div class="pilldiv randompill class">' + random[key3][index] + '</div>');
});
$('.randomclass').html(randomString);
}
function listener() {
$(document).ready(function() {
$(document).on("click", "#randomid div", function() {
data = this.innerHTML;
k1 = Object.keys(random).find(k => random[k].indexOf(data) >= 0)
index = random[k1].indexOf(data);
random[k1].splice(index, 1);
for (let i = 0; i < fruits.length; i++) {
if (fruits[i].fruit === data) {
if (fruits[i].type === "1") {
red[key].push(data);
} else {
green[key2].push(data);
}
}
}
$(".total_count_Green_Fruits").html(key2 + ': ' + green[key2].length);
var element = $(this).detach();
$('#combineid').prepend('<div class="new-green-fruit pilldiv class ">' + element.html() + '</div>');
});
});
$('body').on('click', 'div.new-green-fruit', function() {
data2 = this.innerHTML;
for (let i = 0; i < fruits.length; i++) {
if (fruits[i].fruit === data2) {
if (fruits[i].type === "1") {
k2 = Object.keys(red).find(k => red[k].indexOf(data2) >= 0);
index2 = red[k2].indexOf(data2);
red[k2].splice(index2, 1);
} else {
k2 = Object.keys(green).find(k => green[k].indexOf(data2) >= 0);
index2 = green[k2].indexOf(data2);
green[k2].splice(index2, 1);
}
}
}
random[key3].push(data2);
$(this).detach();
var element2 = $(this).detach();
$('#randomid').prepend('<div class="pilldiv randompill class" >' + element2.html() + '</div>');
});
}
redraw();
listener();
var testing = JSON.stringify(green);
.pilldiv {
padding: 8px 15px;
text-align: center;
font-size: 15px;
border-radius: 25px;
color: Black;
margin: 2px;
}
.randompill:after{
content: "\002B";
float: left;
width:16px;
}
.new-green-fruit:after{
content: "\292B";
float: left;
width:16px;
}
.redpill {
background-color: Pink;
cursor:default;
}
.greenpill {
background-color: SpringGreen;
cursor:default;
}
.randompill {
background-color: LightBlue;
cursor:pointer;
}
.class {
font-family: Open Sans;
}
.center {
display: flex;
justify-content: center;
}
.wrappingflexbox {
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.top {
margin-bottom: 20px
}
h3{
font-weight: normal;
}
.panel {
display: table;
height: 100%;
width: 60%;
background-color:white;
border: 1px solid black;
margin-left: auto;
margin-right: auto;
}
.new-green-fruit{
background-color: LightBlue;
cursor:pointer;
}
.top{
margin-bottom:30px;
}
<!DOCTYPE html>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html>
<head>
<meta charset="utf-8" />
<link rel="shortcut icon" href="//#" />
</head>
<body>
<div class="panel">
<div style="float:left;width:calc(50% - 5px);">
<h3 class="class center">Total Fruits</h3>
<div id="combineid" class="combineclass wrappingflexbox top"></div>
</div>
<div style="float:right;width:calc(50% - 5px)">
<h3 class="class center">Random Fruits</h3>
<div id="randomid" class="randomclass wrappingflexbox top"></div>
</div>
</div>
</body>
</html>
It is working fine as expected. Look into the code base properly may be you are missing something.
var greenFruits = ["Watermelon", "Durian", "Avacado", "Lime", "Honeydew"];
console.log("Green Fruits Object : ", greenFruits);
console.log("Green Fruits String : ", JSON.stringify(greenFruits));
greenFruits.push("Guava");
console.log("Green Fruits Object : ", greenFruits);
console.log("Green Fruits String : ", JSON.stringify(greenFruits));

Categories

Resources