Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Weird bug occurring for Event listeners( I think)

Whenever I click either ‘Reset’, ‘Color Black’, or ‘Erase’ randomly the entire grid will color in black. If that happens and I click Erase I can clear them off and then sometimes randomly the excess black that was randomly created will disappear. Not really sure what the issue is. I THINK it may be an issue with how the Event Listeners are set up, but this is the only configuration of them that gets the buttons to work. Any ideas what the issue might be?

let blackBtn = document.querySelector('#black');
let eraseBtn = document.querySelector('#eraser');
let resetBtn = document.querySelector('#reset');
let resize = document.querySelector('.resize');
let value = 16; // For default 16x16 grid size

//Create grid
function createGrid(size = value) {
  grid.style["grid-template-rows"] = `repeat(${size}, 1fr)`;
  grid.style["grid-template-columns"] = `repeat(${size}, 1fr)`;
  for (let i = 0; i < size * size; i++) {
    const block = document.createElement('div');
    block.className = 'block';
    grid.appendChild(block);
  }
  grid.addEventListener("mouseover", colorBlack);
  resize.addEventListener("click", resizeGrid);
  resetBtn.addEventListener("click", clearGrid);
  eraseBtn.addEventListener("click", eraseColor);
  blackBtn.addEventListener("click", blackPaint);

}

//Resize the grid
function resizeGrid() {
  const newSize = parseInt(prompt("New Size: ", 16));
  grid.innerHTML = '';
  resize.removeEventListener("click", resizeGrid);
  grid.removeEventListener("mouseover", colorBlack);
  createGrid(newSize);
}

//Fill in background color of black
function colorBlack(e) {
  if (e.target.className !== "block") return false;
  e.target.style.backgroundColor = 'black';
}

//Clear background color from grid
function clearGrid(size, newSize) {
  grid.innerHTML = '';
  resize.removeEventListener("click", resizeGrid);
  grid.removeEventListener("mouseover", colorBlack);
  createGrid();
}

//Colors divs black after clicking 'Color Black'
function blackPaint(e) {
  grid.removeEventListener("mouseover", eraseColor);
  grid.addEventListener("mouseover", (e) => {
    e.target.style.backgroundColor = 'black';
  })
}

//Colors over black divs with white to 'erase' it
function eraseColor(e) {
  grid.removeEventListener("mouseover", colorBlack);
  grid.addEventListener("mouseover", (e) => {
    e.target.style.backgroundColor = 'white';
  })
}

createGrid();
* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}

#grid {
  width: 20rem;
  height: 20rem;
  border: 1px solid #333;
  display: grid;
  flex-wrap: grid;
}

.block {
  border: 1px solid black;
}
<!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">
  <title>Etch-A-Sketch</title>
  <link rel="stylesheet" href="style.css">
</head>

<body>
  <header>
    <p>Etch-A-Sketch</p>
  </header>
  <div class="gameBoard">
    <div id="actions">
      <button class="resize">Resize</button>
      <button id="reset">Reset</button>
      <button id="black">Color Black</button>
      <button id="eraser">Eraser</button>
    </div>
    <div id='grid'></div>
    <div class="block"></div>
  </div>

  <script src="script.js"></script>
</body>

</html>

>Solution :

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

When you click on Black or Erase, you add event listeners that call anonymous functions. These can’t be removed with removeEventListener() when you switch modes. So these old event listeners continue to run, erasing and filling in elements.

You should have two functions, colorBlack() and colorWhite(), and switch between them in the mouseover event listener. Also, when you reset or resize, you should go back to black.

The problem with Clear is that it calls createGrid(), which adds all the event listeners again. You remove some of the old listeners before you call it, but not all, so you get duplication. You should separate creating the grid and adding the event listeners, so you don’t repeat the listeners, and then you wouldn’t need to remove them.

let blackBtn = document.querySelector('#black');
let eraseBtn = document.querySelector('#eraser');
let resetBtn = document.querySelector('#reset');
let resize = document.querySelector('.resize');
let value = 16; // For default 16x16 grid size

//Create grid
function createGrid(size = value) {
  grid.style["grid-template-rows"] = `repeat(${size}, 1fr)`;
  grid.style["grid-template-columns"] = `repeat(${size}, 1fr)`;
  for (let i = 0; i < size * size; i++) {
    const block = document.createElement('div');
    block.className = 'block';
    grid.appendChild(block);
  }
}

function addListeners() {
  grid.addEventListener("mouseover", colorBlack);
  resize.addEventListener("click", resizeGrid);
  resetBtn.addEventListener("click", clearGrid);
  eraseBtn.addEventListener("click", eraseColor);
  blackBtn.addEventListener("click", blackPaint);
}

//Resize the grid
function resizeGrid() {
  const newSize = parseInt(prompt("New Size: ", 16));
  grid.innerHTML = '';
  createGrid(newSize);
  blackPaint();
}

//Fill in background color of black
function colorBlack(e) {
  if (e.target.className !== "block") return false;
  e.target.style.backgroundColor = 'black';
}

//Fill in background color of white
function colorWhite(e) {
  if (e.target.className !== "block") return false;
  e.target.style.backgroundColor = 'white';
}

//Clear background color from grid
function clearGrid(size, newSize) {
  grid.innerHTML = '';
  createGrid();
  blackPaint();
}

//Colors divs black after clicking 'Color Black'
function blackPaint(e) {
  grid.removeEventListener("mouseover", colorWhite);
  grid.addEventListener("mouseover", colorBlack);
}

//Colors over black divs with white to 'erase' it
function eraseColor(e) {
  grid.removeEventListener("mouseover", colorBlack);
  grid.addEventListener("mouseover", colorWhite);
}

createGrid();
addListeners();
* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}

#grid {
  width: 20rem;
  height: 20rem;
  border: 1px solid #333;
  display: grid;
  flex-wrap: grid;
}

.block {
  border: 1px solid black;
}
<!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">
  <title>Etch-A-Sketch</title>
  <link rel="stylesheet" href="style.css">
</head>

<body>
  <header>
    <p>Etch-A-Sketch</p>
  </header>
  <div class="gameBoard">
    <div id="actions">
      <button class="resize">Resize</button>
      <button id="reset">Reset</button>
      <button id="black">Color Black</button>
      <button id="eraser">Eraser</button>
    </div>
    <div id='grid'></div>
    <div class="block"></div>
  </div>

  <script src="script.js"></script>
</body>

</html>
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading