user16343752
user16343752

Reputation:

How can I trigger an event on an element that is dynamically created?

I'm working on an Etch-A-Sketch project. I've dynamically created a 16x16 grid, the squares change colour on mouseover. When the reset button is clicked, I want the squares to turn back to white again, however I keep getting the error "Cannot set property 'backgroundColor' of undefined". Any hints are appreciated.

/*****Create grid *****/
for (i = 0; i < 16; i++) {
const grid = document.querySelector(".grid");
const row = document.createElement("div");
grid.appendChild(row);
for (j = 0; j < 16; j++) {
    const column = document.createElement("div");

    column.style.height = "20px";
    column.style.width = "20px";
    column.style.border = "solid black 2px";
    column.classList.add("row");

    grid.appendChild(column);
};
};

/*****Random color picker for grid square*****/
let gridSquare = document.querySelectorAll(".row");

gridSquare.forEach(function (item) {
item.addEventListener("mouseover", function () {
    const hex = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "A", "B", "C", "D", "E", "F"];
    let hexColour = "#";
    for (i = 0; i < 6; i++) {
        hexColour += hex[Math.floor(Math.random() * hex.length)];
    };
    item.style.backgroundColor = hexColour;
});
});

/*****Reset button******/
const resetButton = document.querySelector(".reset");

resetButton.addEventListener("click", function() {
gridSquare.style.backgroundColor = "white";
});

Upvotes: 0

Views: 95

Answers (3)

Mara Black
Mara Black

Reputation: 1751

You need to iterate through each square created.. the document.querySelectorAll(".row"); return an array so basically you tried to set the background to an array, which is not possible

/*****Create grid *****/
for (i = 0; i < 16; i++) {
  const grid = document.querySelector(".grid");
  const row = document.createElement("div");
  grid.appendChild(row);
  for (j = 0; j < 16; j++) {
    const column = document.createElement("div");

    column.style.height = "20px";
    column.style.width = "20px";
    column.style.border = "solid black 2px";
    column.classList.add("row");

    grid.appendChild(column);
  };
};

/*****Random color picker for grid square*****/
let gridSquare = document.querySelectorAll(".row");

gridSquare.forEach(function(item) {
  item.addEventListener("mouseover", function() {
    const hex = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "A", "B", "C", "D", "E", "F"];
    let hexColour = "#";
    for (i = 0; i < 6; i++) {
      hexColour += hex[Math.floor(Math.random() * hex.length)];
    };
    item.style.backgroundColor = hexColour;
  });
});

/*****Reset button******/
const resetButton = document.querySelector(".reset");

resetButton.addEventListener("click", function() {
  gridSquare.forEach(function(item) {
    item.style.backgroundColor = "white";
  })

});
<button class="reset"> reset </button>
<div class="grid"></div>

Upvotes: 0

Soumya
Soumya

Reputation: 146

It's probably because the gridSquare contains multiple document elements as you specified querySelectorAll when defining the variable gridSquare.The style.backgroundColor only works for one element so what you could do is iterate through the gridSquare variable and change the style just like below:

resetButton.addEventListener("click", function() {
    gridSquare.forEach(function(square) {
        square.style.backgroundColor = "white";
    })
});

Upvotes: 0

benoit_mire
benoit_mire

Reputation: 31

You could loop through your grid squares when reset is clicked.

/*****Reset button******/
const resetButton = document.querySelector(".reset");

resetButton.addEventListener("click", function() {
   gridSquare.forEach( function(item) { 
     item.style.backgroundColor = "white";
   }
});

Upvotes: 1

Related Questions