Optimize generation of random colours - javascript

I am just starting out with Javascript and I made my first ever little project so I apologize if the code is bad and hurts your eyes.
I made a color palette generator that creates random hex color codes looping through an array.
I was wondering if there is a better way to do it, perhaps using only one loop and get three different hex codes at the same time?
//declare variables to store color codes visible on dom
const hexCode01 = document.querySelector('.hex-color-code-01');
const hexCode02 = document.querySelector('.hex-color-code-02');
const hexCode03 = document.querySelector('.hex-color-code-03');
//declare variables to store color each box
const box01 = document.querySelector('.box-01');
const box02 = document.querySelector('.box-02');
const box03 = document.querySelector('.box-03');
//declare variables to store action button
const changeBtn = document.querySelector('.change-button');
//declare array to store hex digits
const hexValues = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"];
changeBtn.addEventListener("click", () => {
//change button content after first click
if (changeBtn.innerHTML === 'Generate Palette') changeBtn.innerHTML = 'Generate New Palette';
else {
changeBtn.innerHTML = 'Generate New Palette';
}
let activeHex1 = "#";
let activeHex2 = "#";
let activeHex3 = "#";
//generate first color
for (let i = 0; i < 6; i++) {
const indexBox1 = Math.floor(Math.random() * hexValues.length);
activeHex1 += hexValues[indexBox1];
}
//generate second color
for (let i = 0; i < 6; i++) {
const indexBox2 = Math.floor(Math.random() * hexValues.length);
activeHex2 += hexValues[indexBox2];
}
//generate thitd color
for (let i = 0; i < 6; i++) {
const indexBox3 = Math.floor(Math.random() * hexValues.length);
activeHex3 += hexValues[indexBox3];
}
let bodyColor1 = (hexCode01.innerHTML = activeHex1);
let bodyColor2 = (hexCode02.innerHTML = activeHex2);
let bodyColor3 = (hexCode03.innerHTML = activeHex3);
box01.style.backgroundColor = bodyColor1;
box02.style.backgroundColor = bodyColor2;
box03.style.backgroundColor = bodyColor3;
});
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
height: 100vh;
width: 100vw;
font-family: arial, sans-serif;
font-size: 1rem;
display: flex;
justify-content: center;
align-items: center;
}
.color-box {
width: 33.333%;
height: 100%;
border: 1px solid black;
text-transform: uppercase;
display: flex;
justify-content: center;
align-items: center;
background: #ffffff;
}
button {
background: none;
border: 2px solid #000;
bottom: 1rem;
border-radius: 50px;
padding: 1rem;
position: fixed;
font-family: arial, sans-serif;
font-size: 0.8rem;
text-transform: uppercase;
color: #000;
cursor: pointer;
}
button:hover {
background-color: rgba(255, 255, 255, 0.3);
}
button:active {
color: #fdfdfd;
border-color: #fdfdfd;
}
<div class="color-box box-01">
<div class="hex-color-code-01">#ffffff</div>
</div>
<div class="color-box box-02">
<div class="hex-color-code-02">#ffffff</div>
</div>
<div class="color-box box-03">
<div class="hex-color-code-03">#ffffff</div>
</div>
<button class="change-button">Generate Palette</button>
Thanks

Please use below code where I have done it using one loop:
for (let i = 0; i < 6; i++) {
const indexBox1 = Math.floor(Math.random() * hexValues.length);
const indexBox2 = Math.floor(Math.random() * hexValues.length);
const indexBox3 = Math.floor(Math.random() * hexValues.length);
activeHex1 += hexValues[indexBox1];
activeHex2 += hexValues[indexBox2];
activeHex3 += hexValues[indexBox3];
}
Here is jsfiddle: https://jsfiddle.net/0yhubLn1/

you could use one loop like so:
for (let i = 0; i < 6; i++) {
const indexBox1 = Math.floor(Math.random() * hexValues.length);
activeHex1 += hexValues[indexBox1];
const indexBox2 = Math.floor(Math.random() * hexValues.length);
activeHex2 += hexValues[indexBox2];
const indexBox3 = Math.floor(Math.random() * hexValues.length);
activeHex3 += hexValues[indexBox3];
}
Hope that is what you imagined😊.

const hexValues = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"];
document.querySelector('.change-button').addEventListener("click", () => {
document.querySelector('.change-button').innerHTML = 'Generate New Palette';
let activeHex = [];
for (let i = 0; i < 3; i++) {
activeHex[i] = '#';
for (let j = 0; j < 6; j++) {
activeHex[i] += hexValues[Math.floor(Math.random() * hexValues.length)];
}
document.querySelector('.box-' + i).style.backgroundColor = (document.querySelector('.hex-color-code-' + i).innerHTML = activeHex[i]);
}
});
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
height: 100vh;
width: 100vw;
font-family: arial, sans-serif;
font-size: 1rem;
display: flex;
justify-content: center;
align-items: center;
}
.color-box {
width: 33.333%;
height: 100%;
border: 1px solid black;
text-transform: uppercase;
display: flex;
justify-content: center;
align-items: center;
background: #ffffff;
}
button {
background: none;
border: 2px solid #000;
bottom: 1rem;
border-radius: 50px;
padding: 1rem;
position: fixed;
font-family: arial, sans-serif;
font-size: 0.8rem;
text-transform: uppercase;
color: #000;
cursor: pointer;
}
button:hover {
background-color: rgba(255, 255, 255, 0.3);
}
button:active {
color: #fdfdfd;
border-color: #fdfdfd;
}
<div class="color-box box-0">
<div class="hex-color-code-0">#ffffff</div>
</div>
<div class="color-box box-1">
<div class="hex-color-code-1">#ffffff</div>
</div>
<div class="color-box box-2">
<div class="hex-color-code-2">#ffffff</div>
</div>
<button class="change-button">Generate Palette</button>

hexcode = () => {
const hexValues = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"];
let hex = '#';
for (let i = 0; i < 6; i++) {
let index = Math.floor(Math.random() * hexValues.length);
hex += hexValues[index];
}
return hex;
}
console.log(hexcode());
This function will generate a random hex.
let activeHex1 = hexcode();

You don't need the hexValues array.
0 to FFFFFF in hexadecimal is 0 to 16777215 in decimal. You can select a random number between (and including) those two limits and convert to hexadecimal making sure to left pad with 0s. We need to use 16777215 + 1 = 16777216 in the function to ensure 16777215 is a potential output:
function randomColour() {
var randInt = Math.floor(Math.random() * 16777216); // random between 0 and 16777215
var randHex = randInt.toString(16); // convert to hexadecimal
var randColour = "#" + randHex.padStart(6, "0"); // pad left with 0s if hex is less than 6 chars
return randColour; // return the random hex value
}
console.log(randomColour());
To return 3 (or any number of) hex value colours at the same time, use an array mapping:
function randomColour() {
var randInt = Math.floor(Math.random() * 16777216);
var randHex = randInt.toString(16);
var randColour = "#" + randHex.padStart(6, "0");
return randColour;
}
var numColours = 3; // your code has 3 random colours, adjust this for N colours
var colours = Array.from({length: numColours}, function(v) {return randomColour();});
console.log(colours);
This is a more concise way of doing what you mention in your question:
...perhaps using only one loop and get three different hex codes at
the same time?
It's the same as doing this, but just in one line:
function randomColour() {
var randInt = Math.floor(Math.random() * 16777216);
var randHex = randInt.toString(16);
var randColour = "#" + randHex.padStart(6, "0");
return randColour;
}
var colours = [];
var numColours = 3;
for (var i=0; i<numColours; i++) {
colours.push(randomColour());
}
console.log(colours);
Applying this approach in your code:
//declare variables to store color codes visible on dom
const hexCode01 = document.querySelector('.hex-color-code-01');
const hexCode02 = document.querySelector('.hex-color-code-02');
const hexCode03 = document.querySelector('.hex-color-code-03');
//declare variables to store color each box
const box01 = document.querySelector('.box-01');
const box02 = document.querySelector('.box-02');
const box03 = document.querySelector('.box-03');
//declare variables to store action button
const changeBtn = document.querySelector('.change-button');
changeBtn.addEventListener("click", () => {
//change button content after first click
if (changeBtn.innerHTML === 'Generate Palette') changeBtn.innerHTML = 'Generate New Palette';
else {
changeBtn.innerHTML = 'Generate New Palette';
}
var colours = Array.from({length: 3}, function(v) {return randomColour();});
let bodyColor1 = (hexCode01.innerHTML = colours[0]);
let bodyColor2 = (hexCode02.innerHTML = colours[1]);
let bodyColor3 = (hexCode03.innerHTML = colours[2]);
box01.style.backgroundColor = colours[0];
box02.style.backgroundColor = colours[1];
box03.style.backgroundColor = colours[2];
});
function randomColour() {
var randInt = Math.floor(Math.random() * 16777216);
var randHex = randInt.toString(16);
var randColour = "#" + randHex.padStart(6, "0");
return randColour;
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
height: 100vh;
width: 100vw;
font-family: arial, sans-serif;
font-size: 1rem;
display: flex;
justify-content: center;
align-items: center;
}
.color-box {
width: 33.333%;
height: 100%;
border: 1px solid black;
text-transform: uppercase;
display: flex;
justify-content: center;
align-items: center;
background: #ffffff;
}
button {
background: none;
border: 2px solid #000;
bottom: 1rem;
border-radius: 50px;
padding: 1rem;
position: fixed;
font-family: arial, sans-serif;
font-size: 0.8rem;
text-transform: uppercase;
color: #000;
cursor: pointer;
}
button:hover {
background-color: rgba(255, 255, 255, 0.3);
}
button:active {
color: #fdfdfd;
border-color: #fdfdfd;
}
<div class="color-box box-01">
<div class="hex-color-code-01">#ffffff</div>
</div>
<div class="color-box box-02">
<div class="hex-color-code-02">#ffffff</div>
</div>
<div class="color-box box-03">
<div class="hex-color-code-03">#ffffff</div>
</div>
<button class="change-button">Generate Palette</button>

I left out most of the styling and frills to focus on JavaScript hex generation optimization:
function generate() {
var colorBoxes = document.getElementsByClassName("color-box");
for (var i = 0; i < colorBoxes.length; i++) colorBoxes[i].innerHTML = colorBoxes[i].style.background = "#" + ("00000" + Math.floor(Math.random() * 16777216).toString(16)).slice(-6);
}
.color-box {
display: inline-block;
padding: 20px;
margin-top: 20px;
}
<div><button onclick="generate();">Generate Palette</button></div>
<div class="color-box"></div>
<div class="color-box"></div>
<div class="color-box"></div>
If you want the color generation to be more random, you can use rando.js instead, like this:
console.log("#" + ("00000" + rando(16777215).toString(16)).slice(-6));
<script src="http://randojs.com/2.0.0.js"></script>

Related

onclick event not picking up className elements to append - showing error

I am not sure why my code is not picking up my selections and appending then to my array when the submit button is clicked. I am getting the following error...
"modals.js:103 Uncaught TypeError: Cannot read properties of null (reading 'length') at submit_button.onclick"
My code adds 'button focus' to the className when selected.
I want to take those selections and append them to my an array.
For some reason it does not detect any elements with the className of '.btn.button-focus'.
Any ideas?
var container = document.getElementById('my_dataviz');
var array = ["One", "Two", "Three", "Four", "Five", "Six",
"Seven", "Eight", "Nine", "Ten"
]
let identifier = 0;
let SelectCount = 0;
array.forEach(element => {
const button = document.createElement("button");
button.className = "btn";
button.id = element;
button.value = element;
button.type = "button";
const text = document.createTextNode(element);
button.appendChild(text);
container.appendChild(button);
});
let btn = document.getElementsByClassName("btn");
for (let i = 0; i < btn.length; i++) {
(function(index) {
btn[index].addEventListener("click", function() {
console.log("Clicked Button: " + index);
let isPresent = false;
this.classList.forEach(function(e, i) {
if (e == "button-focus") {
isPresent = true;
} else {
isPresent = false;
}
});
if (isPresent) {
this.classList.remove("button-focus");
SelectCount -= 1;
document.querySelectorAll('.btn').forEach(item => {
if (!item.classList.value.includes('button-focus')) item.disabled = false
})
} else {
this.classList.add("button-focus");
SelectCount += 1;
if (SelectCount > 2) {
document.querySelectorAll('.btn').forEach(item => {
if (!item.classList.value.includes('button-focus')) item.disabled = true
})
}
}
})
})(i)
}
const dataResults = []
let results = document.querySelector('.btn.button-focus');
let submit_button = document.querySelector('.modal-btn');
submit_button.onclick = function() {
for (let i = 0; i < results.length; ++i) {
dataResults.push(results)
console.log(results)
}
}
:root {
--primary_orange: #fea501;
}
.my_dataviz {
width: auto;
height: auto;
margin-top: 15px;
margin-bottom: 15px;
display: flex;
flex-wrap: wrap;
align-content: center;
justify-content: space-evenly;
}
.my_dataviz button {
font-family: "walkway";
font-size: 16px;
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: center;
width: 130px;
height: 25px;
background-color: Transparent;
-webkit-tap-highlight-color: transparent;
background-repeat:no-repeat;
border: none;
letter-spacing: 1.6px;
margin: 10px;
border: 1px solid transparent;
}
.my_dataviz button:hover {
box-sizing: border-box;
background-color: var(--primary_orange);
color: var(--dark);
font-weight: bold;
border: 1px solid #000;
border-radius: 5px;
cursor: pointer;
/*box-shadow: var(--shadow);*/
}
.btn.button-focus {
background-color: var(--primary_orange);
color: var(--dark);
font-weight: bold;
border: 1px solid #000;
border-radius: 5px;
}
.modal-footer {
display: flex;
flex-wrap: wrap;
justify-content: center;
height: 50px;
align-items: center;
text-align: center;
background: var(--primary_med);
border-bottom-left-radius: 10px;
border-bottom-right-radius: 10px;
}
.modal-footer .modal-btn {
font-family: "walkway";
font-size: 16px;
font-weight: bold;
width: 100px;
height: 28px;
border-radius: 5px;
align-items: center;
letter-spacing: 1.6px;
box-shadow: var(--shadow);
}
<div class="my_dataviz" id="my_dataviz">
</div>
<div class="modal-footer">
<input class="modal-btn" type="button" value="Select it" />
</div>
It should run querySelector when the user presses the submit button.
const dataResults = []
let results = document.querySelector('.btn.button-focus'); // remove this line
let submit_button = document.querySelector('.modal-btn');
submit_button.onclick = function() {
dataResults = document.querySelectorAll('.btn.button-focus') // Edit
console.log(dataResults)
}
}
submit_button.onclick = function() {
if(results == null) return;
for (let i = 0; i < results.length; ++i) {
dataResults.push(results)
console.log(results)
}
}
querySelector returns null if it didn't find wanted elements.
But what you want anyways is change querySelector to querySelectorAll and use this code then:
submit_button.onclick = function() {
if(results.length == 0) return;
for (let i = 0; i < results.length; i++) {
dataResults.push(results[i])
console.log(results[i])
}
}
(I made multiple changes to your code which changed the functionality according to what I think you wanted to do (I didn't read what is your purpose in the code))

Loops with unexpected result

This is a color guessing game I'm working on. Basically it allows users to select a color out of six, and output correct if the color is the same as mentioned in the title or output try again if the color is wrong. When I try the first game, everything seems fine but when I select play again and select the colors again, an unexpected recursion occurs and I don't know where's the problem. Here is my code:
window.onload = () => {
"use strict";
let header = document.getElementsByTagName("header")[0];
let titleColor = document.getElementById("title_color");
let nav = document.getElementsByTagName("nav")[0];
let newColors = document.getElementById("new_colors");
let prompt = document.getElementById("prompt");
let easy = document.getElementById("easy");
let hard = document.getElementById("hard");
let active = document.getElementsByClassName("active")[0];
let colors = document.querySelectorAll("[id^=color]");
const initialize = () => {
let t = Math.floor(Math.random() * 5);
for (let i = 0; i < colors.length; i++) {
let r = Math.floor(Math.random() * 255);
let g = Math.floor(Math.random() * 255);
let b = Math.floor(Math.random() * 255);
colors[i].style.backgroundColor = `rgb(${r}, ${g}, ${b})`;
}
titleColor.innerHTML = colors[t].style.backgroundColor;
addingEventHandlers(t);
}
const addingEventHandlers = t => {
for (let i = 0; i < colors.length; i++) {
colors[i].addEventListener("click", () => {
console.log(i);
if (t === i) {
header.style.backgroundColor = colors[t].style.backgroundColor;
for (let j = 0; j < nav.children.length; j++) {
if (nav.children[j] === active) {
nav.children[j].style.color = "rgb(FF, FF, FF)";
nav.children[j].style.backgroundColor = colors[t].style.backgroundColor;
} else {
nav.children[j].style.color = colors[t].style.backgroundColor;
nav.children[j].style.backgroundColor = "rgb(FF, FF, FF)";
}
}
for (let j = 0; j < colors.length; j++) {
colors[j].style.backgroundColor = colors[t].style.backgroundColor;
}
prompt.innerHTML = "Correct";
newColors.innerHTML = "Play Again";
newColors.addEventListener("click", () => initialize())
} else {
console.log(i);
colors[i].style.transitionProperty = "background-color";
colors[i].style.transitionDuration = "1s";
colors[i].style.transitionTimingFunction = "ease-in-out";
colors[i].style.backgroundColor = "rgb(0, 0, 0)";
prompt.innerHTML = "Try Again";
newColors.innerHTML = "New Colors";
newColors.addEventListener("click", () => initialize())
}
})
}
}
initialize();
}
* {
box-sizing: border-box;
}
body {
margin: 0;
text-transform: uppercase;
font-family:'Courier New', Courier, monospace;
font-weight: normal;
font-size: 100%;
text-align: center;
}
header {
color: white;
background-color: navy;
margin: 0;
}
header>h3 {
font-size: 2em;
margin: 0;
}
header>h1 {
font-size: 4em;
margin: 0;
}
nav {
background-color: white;
color: navy;
position: relative;
height: 38px;
}
nav>button {
background-color: white;
color: navy;
border: none;
font-size: 1.5em;
padding: 5px;
text-transform: uppercase;
}
#new_colors {
position: absolute;
left: 20%;
}
#easy {
position: absolute;
left: 62%;
}
#hard {
position: absolute;
left: 72%;
}
nav>button:not(.active):hover {
cursor: pointer;
background-color: navy;
color: white;
}
button.active {
cursor: pointer;
background-color: navy;
color: white;
border: none;
}
#container {
background-color: black;
display: grid;
grid-gap: 20px;
align-content: center;
justify-content: center;
width: 100%;
height: 792px;
}
[id^=color] {
border-radius: 10px;
background-color: white;
width: 200px;
height: 200px;
}
[id^=color]:hover {
cursor: pointer;
opacity: 0.9;
}
#color1 {
grid-area: 1 / 1 / 2 / 2;
}
#color2 {
grid-area: 1 / 2 / 2 / 3;
}
#color3 {
grid-area: 1 / 3 / 2 / 4;
}
#color4 {
grid-area: 2 / 1 / 3 / 2;
}
#color5 {
grid-area: 2 / 2 / 3 / 3;
}
#color6 {
grid-area: 2 / 3 / 3 / 4;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="keywords" content="color guessing game">
<meta name="description" content="color guessing game">
<meta name="author" content="Nick">
<link rel="stylesheet" href="color_guessing.css">
<script src="color_guessing.js"></script>
</head>
<body>
<header>
<h3>The Great</h3>
<h1 id="title_color"></h1>
<h3>Guessing Game</h3>
</header>
<nav>
<button id="new_colors">New Colors</button>
<button id="prompt"></button>
<button id="easy" >Easy</button>
<button id="hard" class="active">Hard</button>
</nav>
<div id="container">
<div id="color1"></div>
<div id="color2"></div>
<div id="color3"></div>
<div id="color4"></div>
<div id="color5"></div>
<div id="color6"></div>
</div>
</body>
</html>
Just like #Thomas said in the comments you need to check if there is an event already and add an event listener if there is none.
if (!colors[i].onclick) {
// your add event listener code goes here
}
You call addingEventHandlers from within initialise. This means that when initialise is called again (like when you start a new game) you will call addEventListener on the same element a second time, meaning you will call a handler twice when the event occurs. And this only gets worse as you call initialise again and again.
So move the call to addingEventHandlers outside of the initialise function body, so that it only gets called on page load, and then no more.

How to compare whether an element is in two different arrays, and push to a new one if true

I am attemping to create a chess game. I have created 64 divs for the chessboard with the function chessSquares. When I created these I pushed the elements into an array called array which consists of the 64 divs that I created and appended to the chessboard.
The next two functions is the yCoord and xCoord. With these two functions I created div elements with the coordinates for the chessboard and appended to the chessSquares. These elements are the outer elements on the left and top side of the chessboard which display coordinates.
With the following function otherCoord I am trying to make an evaluation where if the id numbers of the elements in array do not match the ID numbers in the array of arrayXYCoord then to push the elements into the array of arrayInnerCoord.
After I do this I will be using a function to assign ID's to the other squares of the chessboard followed by coordinates which can be toggled on and off.
I have tried various ways of doing this such as running two loops at a time and it ends up pushing the id's multiple times into an array and it just seemed really messy. I am looking for a clean way to do this with a simple comparison.
If possible, I would like to use a method from javascript.info/array-methods. Thank you
//Make a button to show or hide the x1 y1's and another button for all the x's and y's
//Center the divs x1 y1 on the sides and top
//
const body = document.querySelector('body');
const chessBoard = document.getElementById('chessBoard');
const toggleStatus = document.getElementById('toggleStatus');
const toggle = document.getElementById('toggle');
let array = []; //Array for chessboard squares (divs);
let arrayXYCoord = []; //Coord for outer X and Y Divs - These are ID numbers
let arrayInnerCoord = []; //Coords for those that are not in the center
//Creating Chessboard blocks (divs) and appending them to chessboard
function chessSquares() {
let divID = 1;
for (i = 0; i < 64; i++) {
let div = document.createElement('div');
div.className = 'chessDivs';
div.id = divID;
chessBoard.appendChild(div);
array.push(div);
divID++;
}
}
chessSquares()
// Adding y Coordinate to side of board; classname is "yOuterCoordinates"
function yCoord() {
let yOuterArray = [1, 9, 17, 25, 33, 41, 49, 57]
for (b = 0; b < yOuterArray.length; b++) {
const yCoord = document.getElementById(yOuterArray[b]);
let yCoordinates = document.createElement('div');
yCoordinates.textContent = 'y-' + yOuterArray[b];
yCoordinates.className = 'yOuterCoordinates';
yCoord.appendChild(yCoordinates);
let yDivs = document.getElementById(yOuterArray[b]);
arrayXYCoord.push(yDivs);
}
}
yCoord();
// Adding x Coordinates to top of board; classname is "xOuterCoordinates"
function xCoord() {
let xOuterArray = [1, 2, 3, 4, 5, 6, 7, 8]
for (b = 0; b < xOuterArray.length; b++) {
const xCoord = document.getElementById(xOuterArray[b]);
let xCoordinates = document.createElement('div');
xCoordinates.textContent = 'x-' + xOuterArray[b];
xCoordinates.className = 'xOuterCoordinates';
xCoord.appendChild(xCoordinates);
let xDivs = document.getElementById(xOuterArray[b]);
arrayXYCoord.push(xDivs);
}
}
xCoord();
//Adding coordinates to rest of board with a class name of "otherCoords"
function otherCoord() {
for (i = 0; i < array.length; i++) {
}
}
otherCoord()
console.log(bodyArray);
const whiteChessPieces = [{}];
const blackChessPieces = [{}];
function chessPieces() {
for (i = 0; i < 8; i++) {
//White Pawns
whiteChessPieces.push({ whitePawns: '&#9817' });
}
for (i = 0; i < 2; i++) {
//White Knights
whiteChessPieces.push({ whiteKnight: '&#9816' });
}
for (i = 0; i < 2; i++) {
//White Bishops
whiteChessPieces.push({ whiteBishop: '&#9815' });
//
}
for (i = 0; i < 2; i++) {
//White Rooks
whiteChessPieces.push({ whiteRook: '&#9814' })
}
whiteChessPieces.push({ whiteQueen: '&#9813' }); //Queen
whiteChessPieces.push({ whiteKing: '&#9812' }); //King
for (i = 0; i < 8; i++) {
//Black Pawns
blackChessPieces.push({ blackPawn: '&#9823' })
}
for (i = 0; i < 2; i++) {
//Black Knight
blackChessPieces.push({ blackKnight: '&#9822' });
}
for (i = 0; i < 2; i++) {
//Black Bishop
blackChessPieces.push({ BlackBishop: '&#9821' });
}
for (i = 0; i < 2; i++) {
//Black Rooks
blackChessPieces.push({ blackRook: '&#9820' });
}
blackChessPieces.push({ blackQueen: '&#9819' });
blackChessPieces.push({ blackKing: '&#9818' });
}
chessPieces();
body,
html {
box-sizing: border-box;
}
body {
background-color: white;
display: flex;
justify-content: center;
align-items: center;
padding: 0;
margin: 0;
position: relative;
}
#chessBoard {
/* width: 32rem;
height: 32rem; */
background-color: rgb(65, 35, 1);
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: center;
align-items: center;
width: 32rem;
margin-top: 4rem;
border: 5px ridge rgb(0, 0, 0)
}
.chessDivs {
width: 4rem;
height: 4rem;
margin: 0;
padding: 0;
background-color: rgb(105, 76, 22);
border: 2.5px groove rgb(126, 124, 124);
box-sizing: border-box;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
display: inherit;
position: relative;
}
.chessDivsNone {
display: none;
}
#dualCoord {
display: flex;
flex-direction: column;
}
#toggle {
position: absolute;
top: 4rem;
right: 2rem;
height: auto;
width: auto;
background-color: black;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
color: white;
font-weight: 900;
font-size: 1.25rem;
border: 5px groove blue;
}
.toggleText {
margin: 0;
margin-top: 1rem;
}
#toggleStatus {
margin: 1.5rem 1rem .75rem 1rem;
font-size: 1.5rem;
color: rgb(23, 212, 55);
}
.xOuterCoordinates {
position: absolute;
bottom: 150%;
}
.yOuterCoordinates {
width: 2rem;
position: absolute;
right: 150%;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Chess Game</title>
<style>
</style>
</head>
<body>
<div id="toggle">
<p class="toggleText">Toggle<br>Coordinates</p>
<p id="toggleStatus">Status - On</p>
</div>
<div id="chessBoard">
</div>
</body>
<script>
// Moved to JavasScript pane
</script>
</html>
JavaScript is a language where things become easier and not as messy as Java.
JavaScript has inbuilt functions for your need. You need not make nested loops like you do in Java while searching in arrays.
JavaScript has an inbuilt function called includes()
Suppose:
array1 = ['cat', 'bat', '2', 'rat', 'mat'];
array2 = ['hat', '2', 'elephant', 'cow', 'bat'];
Now:
array2.includes(array1[0]); //Returns false
array2.includes(array1[2]); //Returns true
array1.includes(array2[4]); //Returns true
array2.includes("elephant"); //Returns true
More information regarding to the array.includes() function can be found at: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes
or at https://www.w3schools.com/jsref/jsref_includes_array.asp
Hope it answers your question.

How to color the right choice and the wrong choice in java script quiz?

I want to color the button with green when user choice the correct answer, and with red when it is wrong but in a same time with color the correct answer with green i try this but it is not work.
this text is to let me to publish the post
/*
I would like to be able to show the user what the correct answer to the question is if the one that they selected was incorrect. I would like to keep it simple, but here is what I am thinking. Once the user submits their answer and if it is incorrect, before moving onto the next question I would like for the incorrect answer to be highlighted in red, and the correct answer to be highlighted in green.
I already have coded whether or not the answer is correct or incorrect, but I haven't been able to figure out how to be able to show the correct answer if an incorrect one is chosen.
*/
function wait(ms){
var start = new Date().getTime();
var end = start;
while(end < start + ms) {
end = new Date().getTime();
}
}
function Quiz(questions) {
this.score = 0;
this.questions = questions;
this.questionIndex = 0;
}
Quiz.prototype.getQuestionIndex = function() {
return this.questions[this.questionIndex];
}
Quiz.prototype.guess = function(answer) {
if(this.getQuestionIndex().isCorrectAnswer(answer)) {
console.log(answer);
this.score++;
}
populateV2();
wait(2000);
this.questionIndex++;
}
Quiz.prototype.isEnded = function() {
return this.questionIndex === this.questions.length;
}
function Question(text, textAnswer, choices, answer) {
this.text = text;
this.textAnswer = textAnswer;
this.choices = choices;
this.answer = answer;
}
Question.prototype.isCorrectAnswer = function(choice) {
document.getElementById("btn0").style.backgroundColor='green';
return this.answer === choice;
}
function populate() {
if(quiz.isEnded()) {
showScores();
}
else {
// show question
var element = document.getElementById("question");
element.innerHTML = quiz.getQuestionIndex().text;
// show textAnswer
var textAnswer = quiz.getQuestionIndex().textAnswer;
for(var i = 0; i < textAnswer.length; i++) {
var element = document.getElementById("textAnswer" + i);
element.innerHTML = textAnswer[i];
}
// show options
var choices = quiz.getQuestionIndex().choices;
for(var i = 0; i < choices.length; i++) {
var element = document.getElementById("choice" + i);
element.innerHTML = choices[i];
guess("btn" + i, choices[i]);
}
showProgress();
}
};
function populateV2() {
console.log("Test");
// show question
var element = document.getElementById("question");
element.innerHTML = quiz.getQuestionIndex().text;
// show textAnswer
var textAnswer = quiz.getQuestionIndex().textAnswer;
for(var i = 0; i < textAnswer.length; i++) {
var element = document.getElementById("textAnswer" + i);
element.innerHTML = textAnswer[i];
}
// show options
var choices = quiz.getQuestionIndex().choices;
for(var i = 0; i < choices.length; i++) {
var element = document.getElementById("choice" + i);
element.innerHTML = choices[i];
}
showProgress();
};
function guess(id, guess) {
var button = document.getElementById(id);
button.onclick = function() {
quiz.guess(guess);
populate();
}
};
function showProgress() {
var currentQuestionNumber = quiz.questionIndex + 1;
var element = document.getElementById("progress");
element.innerHTML = "Question " + currentQuestionNumber + " of " + quiz.questions.length;
};
function showScores() {
var gameOverHTML = "<h1>Result</h1>";
gameOverHTML += "<h2 id='score'> Your scores: " + quiz.score + "</h2>";
var element = document.getElementById("quiz");
element.innerHTML = gameOverHTML;
};
// create questions here
var questions = [
new Question("1.At what age was Harry Potter when he received his Hogwarts letter?",
["A: 9",
"B: 6",
"C: 7"],
["A", "B","C"],
"C"),
new Question("2.Which is not a Hogwarts house?",
["A: Dunder Mifflin",
"B: Ravenclaw",
"C: Slytherin"],
["A", "B","C"],
"A"),
new Question("3.Who teaches Transfiguration at Hogwarts?",
["A: Rubeus Hagrid",
"B: Minerva McGonnagle",
"C: Albus Dumbledore"],
["A", "B","C"],
"B")
];
// create quiz
var quiz = new Quiz(questions);
// display quiz
populate();
body {
background-color: #eeeeee;
}
.grid {
width: 600px;
height: 600px;
margin: 0 auto;
background-color: #fff;
padding: 10px 50px 50px 50px;
border-radius: 50px;
border: 2px solid #cbcbcb;
box-shadow: 10px 15px 5px #cbcbcb;
}
.grid h1 {
font-family: "sans-serif";
background-color: #57636e;
font-size: 60px;
text-align: center;
color: #ffffff;
padding: 2px 0px;
border-radius: 50px;
}
#score {
color: #5A6772;
text-align: center;
font-size: 30px;
}
.grid #question {
font-family: "monospace";
font-size: 20px;
color: #5A6772;
}
.grid1 #textAnswer {
font-family: "monospace";
font-size: 15px;
color: #5A6772;
}
.image {
width: 20%;
}
.buttons {
margin-top: 30px;
}
#btn0, #btn1 {
background-color: #778897;
width: 250px;
font-size: 20px;
color: #fff;
border: 1px solid #1D3C6A;
border-radius: 50px;
margin: 10px 40px 10px 0px;
padding: 10px 10px;
}
#btn2 {
background-color: #778897;
width: 500px;
font-size: 20px;
color: #fff;
border: 1px solid #1D3C6A;
border-radius: 50px;
margin: 10px 40px 10px 20px;
padding: 10px 10px;
}
#btn0:hover, #btn1:hover, #btn2:hover {
cursor: pointer;
background-color: #57636e;
}
#btn0:focus, #btn1:focus, #btn2:focus {
outline: 0;
}
#progress {
color: #2b2b2b;
font-size: 18px;
}
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>Quiz</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<div class="grid">
<div id="quiz">
<h1>Quiz</h1>
<hr style="margin-bottom: 20px">
<p id="question"></p>
<ul class="grid1">
<li id="textAnswer0"></li>
<li id="textAnswer1"></li>
<li id="textAnswer2"></li>
</ul>
<div class="buttons">
<button id="btn0"><span id="choice0"></span></button>
<button id="btn1"><span id="choice1"></span></button>
<button id="btn2"><span id="choice2"></span></button>
</div>
<span id="wrong_answer"></span>
<hr style="margin-top: 50px">
<footer>
<p id="progress">Question x of y</p>
</footer>
</div>
</div>
<script src="app.js"></script>
</body>
</html>
In order to color the right choice with green and the wrong choices with red just select all buttons, compare the content of their <span> element with the right answer and color them accordingly:
function wait(ms) {
var start = new Date().getTime();
var end = start;
while (end < start + ms) {
end = new Date().getTime();
}
}
function Quiz(questions) {
this.score = 0;
this.questions = questions;
this.questionIndex = 0;
}
Quiz.prototype.getQuestionIndex = function() {
return this.questions[this.questionIndex];
}
Quiz.prototype.guess = function(answer) {
if (this.getQuestionIndex().isCorrectAnswer(answer)) {
console.log(answer);
this.score++;
}
populateV2();
wait(2000);
this.questionIndex++;
}
Quiz.prototype.isEnded = function() {
return this.questionIndex === this.questions.length;
}
function Question(text, textAnswer, choices, answer) {
this.text = text;
this.textAnswer = textAnswer;
this.choices = choices;
this.answer = answer;
}
Question.prototype.isCorrectAnswer = function(choice) {
var answer = this.answer;
const buttons = document.querySelectorAll('button');
for (let i = 0; i < buttons.length; i++) {
var letter = buttons[i].getElementsByTagName("span")[0].textContent;
if (letter == answer) {
buttons[i].style.backgroundColor = 'green';
} else {
buttons[i].style.backgroundColor = 'red';
}
}
return this.answer === choice;
}
function populate() {
if (quiz.isEnded()) {
showScores();
} else {
// show question
var element = document.getElementById("question");
element.innerHTML = quiz.getQuestionIndex().text;
// show textAnswer
var textAnswer = quiz.getQuestionIndex().textAnswer;
for (var i = 0; i < textAnswer.length; i++) {
var element = document.getElementById("textAnswer" + i);
element.innerHTML = textAnswer[i];
}
// show options
var choices = quiz.getQuestionIndex().choices;
for (var i = 0; i < choices.length; i++) {
var element = document.getElementById("choice" + i);
element.innerHTML = choices[i];
guess("btn" + i, choices[i]);
}
showProgress();
}
};
function populateV2() {
console.log("Test");
// show question
var element = document.getElementById("question");
element.innerHTML = quiz.getQuestionIndex().text;
// show textAnswer
var textAnswer = quiz.getQuestionIndex().textAnswer;
for (var i = 0; i < textAnswer.length; i++) {
var element = document.getElementById("textAnswer" + i);
element.innerHTML = textAnswer[i];
}
// show options
var choices = quiz.getQuestionIndex().choices;
for (var i = 0; i < choices.length; i++) {
var element = document.getElementById("choice" + i);
element.innerHTML = choices[i];
}
showProgress();
};
function guess(id, guess) {
var button = document.getElementById(id);
button.onclick = function() {
quiz.guess(guess);
populate();
}
};
function showProgress() {
var currentQuestionNumber = quiz.questionIndex + 1;
var element = document.getElementById("progress");
element.innerHTML = "Question " + currentQuestionNumber + " of " + quiz.questions.length;
};
function showScores() {
var gameOverHTML = "<h1>Result</h1>";
gameOverHTML += "<h2 id='score'> Your scores: " + quiz.score + "</h2>";
var element = document.getElementById("quiz");
element.innerHTML = gameOverHTML;
};
// create questions here
var questions = [
new Question("1.At what age was Harry Potter when he received his Hogwarts letter?",
["A: 9",
"B: 6",
"C: 7"
],
["A", "B", "C"],
"C"),
new Question("2.Which is not a Hogwarts house?",
["A: Dunder Mifflin",
"B: Ravenclaw",
"C: Slytherin"
],
["A", "B", "C"],
"A"),
new Question("3.Who teaches Transfiguration at Hogwarts?",
["A: Rubeus Hagrid",
"B: Minerva McGonnagle",
"C: Albus Dumbledore"
],
["A", "B", "C"],
"B")
];
// create quiz
var quiz = new Quiz(questions);
// display quiz
populate();
body {
background-color: #eeeeee;
}
.grid {
width: 600px;
height: 600px;
margin: 0 auto;
background-color: #fff;
padding: 10px 50px 50px 50px;
border-radius: 50px;
border: 2px solid #cbcbcb;
box-shadow: 10px 15px 5px #cbcbcb;
}
.grid h1 {
font-family: "sans-serif";
background-color: #57636e;
font-size: 60px;
text-align: center;
color: #ffffff;
padding: 2px 0px;
border-radius: 50px;
}
#score {
color: #5A6772;
text-align: center;
font-size: 30px;
}
.grid #question {
font-family: "monospace";
font-size: 20px;
color: #5A6772;
}
.grid1 #textAnswer {
font-family: "monospace";
font-size: 15px;
color: #5A6772;
}
.image {
width: 20%;
}
.buttons {
margin-top: 30px;
}
#btn0, #btn1 {
background-color: #778897;
width: 250px;
font-size: 20px;
color: #fff;
border: 1px solid #1D3C6A;
border-radius: 50px;
margin: 10px 40px 10px 0px;
padding: 10px 10px;
}
#btn2 {
background-color: #778897;
width: 500px;
font-size: 20px;
color: #fff;
border: 1px solid #1D3C6A;
border-radius: 50px;
margin: 10px 40px 10px 20px;
padding: 10px 10px;
}
#btn0:hover, #btn1:hover, #btn2:hover {
cursor: pointer;
background-color: #57636e;
}
#btn0:focus, #btn1:focus, #btn2:focus {
outline: 0;
}
#progress {
color: #2b2b2b;
font-size: 18px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="grid">
<div id="quiz">
<h1>Quiz</h1>
<hr style="margin-bottom: 20px">
<p id="question"></p>
<ul class="grid1">
<li id="textAnswer0"></li>
<li id="textAnswer1"></li>
<li id="textAnswer2"></li>
</ul>
<div class="buttons">
<button id="btn0"><span id="choice0"></span></button>
<button id="btn1"><span id="choice1"></span></button>
<button id="btn2"><span id="choice2"></span></button>
</div>
<span id="wrong_answer"></span>
<hr style="margin-top: 50px">
<footer>
<p id="progress">Question x of y</p>
</footer>
</div>
</div>
Note that you have to adjust/restructure your code so that there's a short waiting time before the new question is generated as I think you might want to show the buttons again with the grey background color upon a new question.

by class name counter not work in javascript

i create a counter.
dk = parseInt(document.querySelector('.dm').innerText);
for (var i = 0; i <= dk; i++) {
(function(i) {
setTimeout(function() {
document.querySelector('.dm').innerText = i;
}, i * 100);
})(i);
}
console.log(dk);
.counter { display: flex; }
.dm {
background: tomato;
padding: 15px;
font-size: 5em;
font-weight: 700;
width: 100px;
height: auto;
text-align: center;
margin: 0 2px;
}
<div class="counter">
<div class="dm">40</div>
<div class="dm">30</div>
</div>
problem is only first div counter is working.
can we parse element of innerHTMl by html dom like classname...i try but result is Nan.
i want run all counter if i add same classname with different inner values.
Your problem is that you are using document.querySelector().
When you use document.querySelector('.dm') it will return only the first element matching this selector, you need to use document.querySelectorAll('.dm') to get all the matching elements.
But with multiple elements you will need a loop to do that, because querySelectorAll() will return a nodeList which is a collection(array).
This is how should be your code:
var elements = document.querySelectorAll('.dm');
Array.from(elements).forEach(function(el, ind){
let dk = parseInt(elements[ind].innerText)
for (var i = 0; i <= dk; i++) {
(function(i) {
setTimeout(function() {
elements[ind].innerText = i;
}, i * 100);
})(i);
}
});
Demo:
var elements = document.querySelectorAll('.dm');
Array.from(elements).forEach(function(el, ind){
let dk = parseInt(elements[ind].innerText)
for (var i = 0; i <= dk; i++) {
(function(i) {
setTimeout(function() {
elements[ind].innerText = i;
}, i * 100);
})(i);
}
});
.counter { display: flex; }
.dm {
background: tomato;
padding: 15px;
font-size: 5em;
font-weight: 700;
width: 100px;
height: auto;
text-align: center;
margin: 0 2px;
}
<div class="counter">
<div class="dm">40</div>
<div class="dm">30</div>
</div>
Your question is not very clear, but if I understood correctly, you want both timer to run simultaneous, right?
If so, then the code below should help.
Use the querySelectorAll() to get all elements with same class, then loop through them to get the value and make it increase like you was doing.
const dms = document.querySelectorAll('.dm');
for (let j = 0; j < dms.length; j++){
let dk = dms[j].innerText;
for(let i = 0; i <= dk; i++){
setTimeout(function() {
dms[j].innerText = i;
}, i * 100);
}
console.log(dk);
}
.counter{
display: flex;
}
.dm {
background: tomato;
padding: 15px;
font-size: 5em;
font-weight: 700;
width: 100px;
height: auto;
text-align: center;
margin: 0 2px;
}
<div class="counter">
<div class="dm">40</div>
<div class="dm">30</div>
</div>

Categories

Resources