I am trying to create the Etch a Sketch project for The Odin Project. One of the tasks is to add a button that changes the amount of grids.
How can I make my button have that functionality without it creating 16, 32 or 64 grids every time it is clicked.
Sorry if my code is trash, only a month into coding
const container = document.querySelector('.container')
const squares = document.getElementsByClassName('square')
const eraser = document.getElementsByClassName('eraser')[0]
const randomColorBtn = document.getElementsByClassName('randomColor')[0]
const sixteenBtn = document.getElementById('sixteen')
const thirtyBtn = document.getElementById('thirty')
const sixtyBtn = document.getElementById('sixty')
const resetBtn = document.querySelector('.reset')
resetBtn.addEventListener('click', () => location.reload());
function squaresCreator(numSquares, totalSquares) {
container.style.display = "grid";
container.style.gridTemplateRows = `repeat(${numSquares}, 1fr)`;
container.style.gridTemplateColumns = `repeat(${numSquares}, 1fr)`;
for (let i = 0; i < totalSquares; i ) {
const div = document.createElement('div')
container.appendChild(div)
div.classList.add('square');
}
}
squaresCreator(16, 256);
function squareColor(backgroundColor) {
for (const square of squares) {
square.addEventListener("mouseover", function color(square) {
square.target.style.backgroundColor = backgroundColor;
});
}
}
let bgColor = 'black';
squareColor(bgColor);
eraser.addEventListener("click", function() {
bgColor = 'white'
return (squareColor(bgColor))
});
const colorArray = [
"AliceBlue",
"AntiqueWhite",
"Aqua",
"Aquamarine",
"Azure",
"Beige",
"Bisque",
"Black",
"BlanchedAlmond",
"Blue",
"BlueViolet",
"Brown",
"BurlyWood",
"CadetBlue",
"Chartreuse",
"Chocolate",
"Coral",
"CornflowerBlue",
"Cornsilk",
"Crimson",
"Cyan",
"DarkBlue",
"DarkCyan",
"DarkGoldenRod",
"DarkGray",
"DarkGrey",
"DarkGreen",
"DarkKhaki",
"DarkMagenta",
"DarkOliveGreen",
"DarkOrange",
"DarkOrchid",
"DarkRed",
"DarkSalmon",
"DarkSeaGreen",
"DarkSlateBlue",
"DarkSlateGray",
"DarkSlateGrey",
"DarkTurquoise",
"DarkViolet",
"DeepPink",
"DeepSkyBlue",
"DimGray",
"DimGrey",
"DodgerBlue",
"FireBrick",
"FloralWhite",
"ForestGreen",
"Fuchsia",
"Gainsboro",
"GhostWhite",
"Gold",
"GoldenRod",
"Gray",
"Grey",
"Green",
"GreenYellow",
"HoneyDew",
"HotPink",
"IndianRed",
"Indigo",
"Ivory",
"Khaki",
"Lavender",
"LavenderBlush",
"LawnGreen",
"LemonChiffon",
"LightBlue",
"LightCoral",
"LightCyan",
"LightGoldenRodYellow",
"LightGray",
"LightGrey",
"LightGreen",
"LightPink",
"LightSalmon",
"LightSeaGreen",
"LightSkyBlue",
"LightSlateGray",
"LightSlateGrey",
"LightSteelBlue",
"LightYellow",
"Lime",
"LimeGreen",
"Linen",
"Magenta",
"Maroon",
"MediumAquaMarine",
"MediumBlue",
"MediumOrchid",
"MediumPurple",
"MediumSeaGreen",
"MediumSlateBlue",
"MediumSpringGreen",
"MediumTurquoise",
"MediumVioletRed",
"MidnightBlue",
"MintCream",
"MistyRose",
"Moccasin",
"NavajoWhite",
"Navy",
"OldLace",
"Olive",
"OliveDrab",
"Orange",
"OrangeRed",
"Orchid",
"PaleGoldenRod",
"PaleGreen",
"PaleTurquoise",
"PaleVioletRed",
"PapayaWhip",
"PeachPuff",
"Peru",
"Pink",
"Plum",
"PowderBlue",
"Purple",
"RebeccaPurple",
"Red",
"RosyBrown",
"RoyalBlue",
"SaddleBrown",
"Salmon",
"SandyBrown",
"SeaGreen",
"SeaShell",
"Sienna",
"Silver",
"SkyBlue",
"SlateBlue",
"SlateGray",
"SlateGrey",
"Snow",
"SpringGreen",
"SteelBlue",
"Tan",
"Teal",
"Thistle",
"Tomato",
"Turquoise",
"Violet",
"Wheat",
"White",
"WhiteSmoke",
"Yellow",
"YellowGreen",
];
randomColorBtn.addEventListener("click", function() {
bgColor = colorArray[Math.floor(Math.random() * colorArray.length)]
return (squareColor(bgColor))
});
(function() {
// Bind Click event to the drop down navigation button
document.querySelector('#nav-button').addEventListener('click', function() {
/* Toggle the CSS closed class which reduces the height of the UL thus
hiding all LI apart from the first */
this.parentNode.parentNode.classList.toggle('closed')
}, false);
})();
sixteenBtn.addEventListener("click", function() {
return (squaresCreator(16, 256), squareColor(bgColor))
})
thirtyBtn.addEventListener("click", function() {
return (squaresCreator(32, 1024), squareColor(bgColor))
})
sixtyBtn.addEventListener("click", function() {
return (squaresCreator(64, 4096), squareColor(bgColor))
})
h1 {
text-align: center;
font-family: Neucha, sans-serif;
}
.container {
margin: 1em auto 0;
height: 500px;
width: 500px;
box-shadow: rgba(0, 0, 0, 0.3) 0px 19px 38px, rgba(0, 0, 0, 0.22) 0px 15px 12px;
}
.square {
border: 1px solid rgba(97, 150, 255, 0.567);
}
div.options {
display: flex;
justify-content: center;
align-items: center;
}
button {
height: 42px;
width: 90px;
background-color: #fff;
border-radius: 15px 225px 255px 15px 15px 255px 225px 15px;
border-style: solid;
border-width: 2px;
box-shadow: rgba(0, 0, 0, .2) 15px 28px 25px -18px;
color: black;
cursor: pointer;
font-family: Neucha, sans-serif;
font-size: 1rem;
transition: all 235ms ease-in-out;
border-bottom-left-radius: 15px 255px;
border-bottom-right-radius: 225px 15px;
border-top-left-radius: 255px 15px;
border-top-right-radius: 15px 225px;
margin-right: 15px;
}
button:hover {
box-shadow: rgba(0, 0, 0, .3) 2px 8px 8px -5px;
transform: translate3d(0, 2px, 0);
}
button:focus {
box-shadow: rgba(0, 0, 0, .3) 2px 8px 4px -6px;
}
nav .drop-down {
overflow: hidden;
/* When ul height is reduced, ensure overflowing li are not shown */
height: 172px;
/* 172px = (38 (li) 5 (li border)) * 4 (number of li) */
width: 130px;
line-height: 30px;
text-align: center;
-webkit-transition: height 0.3s ease;
transition: height 0.3s ease;
background-color: #fff;
border-radius: 15px 225px 255px 15px 15px 255px 225px 15px;
border-style: solid;
border-width: 2px;
padding: 0;
box-shadow: rgba(0, 0, 0, .2) 15px 28px 25px -18px;
color: black;
cursor: pointer;
font-family: Neucha, sans-serif;
font-size: 1rem;
transition: all 235ms ease-in-out;
border-bottom-left-radius: 15px 255px;
border-bottom-right-radius: 225px 15px;
border-top-left-radius: 255px 15px;
border-top-right-radius: 15px 225px;
touch-action: manipulation;
list-style: none;
}
nav .drop-down.closed {
/* When toggled via jQuery this class will reduce the height of the ul which inconjuction
with overflow: hidden set on the ul will hide all list items apart from the first */
/* current li height 38px 5px border */
height: 38px;
}
nav .drop-down li {
border-bottom: 2px solid black;
}
nav .drop-down li a {
display: block;
color: black;
text-decoration: none;
padding: 6px;
/* Larger touch target area */
}
nav .drop-down li:first-child a:after {
content: "\25BC";
float: right;
margin-left: -30px;
/* Excessive -margin to bring link text back to center */
margin-right: 5px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Neucha&display=swap" rel="stylesheet">
<link rel="stylesheet" href="style.css">
<title>Etch-A-Sketch</title>
</head>
<body>
<h1>Etch-A-Sketch</h1>
<div >
<button >Reset</button>
<button >Eraser</button>
<button title="Selects a random color for you">Color</button>
<nav>
<ul >
<li><a href="#" id="nav-button">Grid size</a></li>
<li><a href="#" id="sixteen">16 x 16</a></li>
<li><a href="#" id="thirty"> x 32</a></i>
<li><a href="#" id="sixty">64 x 64</a></li>
</ul>
</nav>
</div>
<div ></div>
<script src="main.js"></script>
</body>
</html>
CodePudding user response:
I would remove all children from your container
element whenever the squaresCreator
function is called. For example:
while (container.lastElementChild) {
container.removeChild(container.lastElementChild);
}
This should ensure that the grid is reconstructed each time the function is called, instead of simply adding nodes to the existing grid.
Example using your code:
const container = document.querySelector('.container')
const squares = document.getElementsByClassName('square')
const eraser = document.getElementsByClassName('eraser')[0]
const randomColorBtn = document.getElementsByClassName('randomColor')[0]
const sixteenBtn = document.getElementById('sixteen')
const thirtyBtn = document.getElementById('thirty')
const sixtyBtn = document.getElementById('sixty')
const resetBtn = document.querySelector('.reset')
resetBtn.addEventListener('click', () => location.reload());
function squaresCreator(numSquares, totalSquares) {
/* added code */
while (container.lastElementChild) {
container.removeChild(container.lastElementChild);
}
/* end added code */
container.style.display = "grid";
container.style.gridTemplateRows = `repeat(${numSquares}, 1fr)`;
container.style.gridTemplateColumns = `repeat(${numSquares}, 1fr)`;
for (let i = 0; i < totalSquares; i ) {
const div = document.createElement('div')
container.appendChild(div)
div.classList.add('square');
}
}
squaresCreator(16, 256);
function squareColor(backgroundColor) {
for (const square of squares) {
square.addEventListener("mouseover", function color(square) {
square.target.style.backgroundColor = backgroundColor;
});
}
}
let bgColor = 'black';
squareColor(bgColor);
eraser.addEventListener("click", function() {
bgColor = 'white'
return (squareColor(bgColor))
});
const colorArray = [
"AliceBlue",
"AntiqueWhite",
"Aqua",
"Aquamarine",
"Azure",
"Beige",
"Bisque",
"Black",
"BlanchedAlmond",
"Blue",
"BlueViolet",
"Brown",
"BurlyWood",
"CadetBlue",
"Chartreuse",
"Chocolate",
"Coral",
"CornflowerBlue",
"Cornsilk",
"Crimson",
"Cyan",
"DarkBlue",
"DarkCyan",
"DarkGoldenRod",
"DarkGray",
"DarkGrey",
"DarkGreen",
"DarkKhaki",
"DarkMagenta",
"DarkOliveGreen",
"DarkOrange",
"DarkOrchid",
"DarkRed",
"DarkSalmon",
"DarkSeaGreen",
"DarkSlateBlue",
"DarkSlateGray",
"DarkSlateGrey",
"DarkTurquoise",
"DarkViolet",
"DeepPink",
"DeepSkyBlue",
"DimGray",
"DimGrey",
"DodgerBlue",
"FireBrick",
"FloralWhite",
"ForestGreen",
"Fuchsia",
"Gainsboro",
"GhostWhite",
"Gold",
"GoldenRod",
"Gray",
"Grey",
"Green",
"GreenYellow",
"HoneyDew",
"HotPink",
"IndianRed",
"Indigo",
"Ivory",
"Khaki",
"Lavender",
"LavenderBlush",
"LawnGreen",
"LemonChiffon",
"LightBlue",
"LightCoral",
"LightCyan",
"LightGoldenRodYellow",
"LightGray",
"LightGrey",
"LightGreen",
"LightPink",
"LightSalmon",
"LightSeaGreen",
"LightSkyBlue",
"LightSlateGray",
"LightSlateGrey",
"LightSteelBlue",
"LightYellow",
"Lime",
"LimeGreen",
"Linen",
"Magenta",
"Maroon",
"MediumAquaMarine",
"MediumBlue",
"MediumOrchid",
"MediumPurple",
"MediumSeaGreen",
"MediumSlateBlue",
"MediumSpringGreen",
"MediumTurquoise",
"MediumVioletRed",
"MidnightBlue",
"MintCream",
"MistyRose",
"Moccasin",
"NavajoWhite",
"Navy",
"OldLace",
"Olive",
"OliveDrab",
"Orange",
"OrangeRed",
"Orchid",
"PaleGoldenRod",
"PaleGreen",
"PaleTurquoise",
"PaleVioletRed",
"PapayaWhip",
"PeachPuff",
"Peru",
"Pink",
"Plum",
"PowderBlue",
"Purple",
"RebeccaPurple",
"Red",
"RosyBrown",
"RoyalBlue",
"SaddleBrown",
"Salmon",
"SandyBrown",
"SeaGreen",
"SeaShell",
"Sienna",
"Silver",
"SkyBlue",
"SlateBlue",
"SlateGray",
"SlateGrey",
"Snow",
"SpringGreen",
"SteelBlue",
"Tan",
"Teal",
"Thistle",
"Tomato",
"Turquoise",
"Violet",
"Wheat",
"White",
"WhiteSmoke",
"Yellow",
"YellowGreen",
];
randomColorBtn.addEventListener("click", function() {
bgColor = colorArray[Math.floor(Math.random() * colorArray.length)]
return (squareColor(bgColor))
});
(function() {
// Bind Click event to the drop down navigation button
document.querySelector('#nav-button').addEventListener('click', function() {
/* Toggle the CSS closed class which reduces the height of the UL thus
hiding all LI apart from the first */
this.parentNode.parentNode.classList.toggle('closed')
}, false);
})();
sixteenBtn.addEventListener("click", function() {
return (squaresCreator(16, 256), squareColor(bgColor))
})
thirtyBtn.addEventListener("click", function() {
return (squaresCreator(32, 1024), squareColor(bgColor))
})
sixtyBtn.addEventListener("click", function() {
return (squaresCreator(64, 4096), squareColor(bgColor))
})
h1 {
text-align: center;
font-family: Neucha, sans-serif;
}
.container {
margin: 1em auto 0;
height: 500px;
width: 500px;
box-shadow: rgba(0, 0, 0, 0.3) 0px 19px 38px, rgba(0, 0, 0, 0.22) 0px 15px 12px;
}
.square {
border: 1px solid rgba(97, 150, 255, 0.567);
}
div.options {
display: flex;
justify-content: center;
align-items: center;
}
button {
height: 42px;
width: 90px;
background-color: #fff;
border-radius: 15px 225px 255px 15px 15px 255px 225px 15px;
border-style: solid;
border-width: 2px;
box-shadow: rgba(0, 0, 0, .2) 15px 28px 25px -18px;
color: black;
cursor: pointer;
font-family: Neucha, sans-serif;
font-size: 1rem;
transition: all 235ms ease-in-out;
border-bottom-left-radius: 15px 255px;
border-bottom-right-radius: 225px 15px;
border-top-left-radius: 255px 15px;
border-top-right-radius: 15px 225px;
margin-right: 15px;
}
button:hover {
box-shadow: rgba(0, 0, 0, .3) 2px 8px 8px -5px;
transform: translate3d(0, 2px, 0);
}
button:focus {
box-shadow: rgba(0, 0, 0, .3) 2px 8px 4px -6px;
}
nav .drop-down {
overflow: hidden;
/* When ul height is reduced, ensure overflowing li are not shown */
height: 172px;
/* 172px = (38 (li) 5 (li border)) * 4 (number of li) */
width: 130px;
line-height: 30px;
text-align: center;
-webkit-transition: height 0.3s ease;
transition: height 0.3s ease;
background-color: #fff;
border-radius: 15px 225px 255px 15px 15px 255px 225px 15px;
border-style: solid;
border-width: 2px;
padding: 0;
box-shadow: rgba(0, 0, 0, .2) 15px 28px 25px -18px;
color: black;
cursor: pointer;
font-family: Neucha, sans-serif;
font-size: 1rem;
transition: all 235ms ease-in-out;
border-bottom-left-radius: 15px 255px;
border-bottom-right-radius: 225px 15px;
border-top-left-radius: 255px 15px;
border-top-right-radius: 15px 225px;
touch-action: manipulation;
list-style: none;
}
nav .drop-down.closed {
/* When toggled via jQuery this class will reduce the height of the ul which inconjuction
with overflow: hidden set on the ul will hide all list items apart from the first */
/* current li height 38px 5px border */
height: 38px;
}
nav .drop-down li {
border-bottom: 2px solid black;
}
nav .drop-down li a {
display: block;
color: black;
text-decoration: none;
padding: 6px;
/* Larger touch target area */
}
nav .drop-down li:first-child a:after {
content: "\25BC";
float: right;
margin-left: -30px;
/* Excessive -margin to bring link text back to center */
margin-right: 5px;
}
<h1>Etch-A-Sketch</h1>
<div >
<button >Reset</button>
<button >Eraser</button>
<button title="Selects a random color for you">Color</button>
<nav>
<ul >
<li><a href="#" id="nav-button">Grid size</a></li>
<li><a href="#" id="sixteen">16 x 16</a></li>
<li><a href="#" id="thirty"> x 32</a></li>
<li><a href="#" id="sixty">64 x 64</a></li>
</ul>
</nav>
</div>
<div ></div>