Home > Mobile >  How can I resize my grid when I press a button?
How can I resize my grid when I press a button?

Time:12-01

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>

  • Related