Good evening,
I am having trouble using a click event listener to change the background color of a js created div.
I have trolled through the questions but I am stumped as to why , even if I declare the function after the divs have been created an appended it still does not change the color.
The code is below.
<link rel="stylesheet" href="index.css">
<style>
</style>
<script src="script.js" defer > </script>
<body>
<h1> Grid aye? </h1>
<div >
<aside class ="toggleBar"> This is where the switches will go </aside>
<!-- This where the grids are created, using psuedo classes in CSS. -->
<div id="container"></div>
</div>
</body>
</html>
JS
const container = document.getElementById("container");
const gridItem = document.getElementById("grid-item");
// uses a loop to create the required divs
function makeRows(rows, cols) {
container.style.setProperty('--grid-rows', rows);
container.style.setProperty('--grid-cols', cols);
for (c = 0; c < (rows * cols); c ) {
let cell = document.createElement("div");
container.appendChild(cell).className = "grid-item";
};
};
makeRows(16, 16);
function changeGridColor (e) {
e.style.backgroundColor="red";
};
gridItem.addEventListener(`click`,changeGridColor());
Can anyone point me to where I have gone wrong?
I tried declaring the event listener before appending the created divs, but that throws errors in VSCode
CodePudding user response:
const gridItem = document.getElementById("grid-item");
This line will not be correct because no element in your HTML has grid-item
as Id at this moment of the script execution.
You will need to put this line after the makeRows(16, 16);
.
In addition, in container.appendChild(cell).className = "grid-item";
, you add a class, not an id. So const gridItem = document.getElementById("grid-item");
will not be correct and need to be const gridItems = document.querySelectorAll(".grid-item")
.
Because there are multiple div with this class, you will need to loop over them in order to attach the event listener. Instead of gridItem.addEventListener(
click, changeGridColor);
, you will need :
const gridItems = document.querySelectorAll(".grid-item");
for(let gridItem of gridItems) {
gridItem.addEventListener(`click`, changeGridColor);
}
EDIT: and e.style.backgroundColor = "red";
should be e.target.style.backgroundColor = "red";
CodePudding user response:
The other solution is correct that the element does not exist by then. However, if you added more rows, those new rows/grid items will not have the event listener attached.
Instead, you can rely on a more versatile event delegation technique to ensure that all future grid items have the event listener:
// uses a loop to create the required divs
function makeRows(rows, cols) {
container.style.setProperty('--grid-rows', rows);
container.style.setProperty('--grid-cols', cols);
for (c = 0; c < (rows * cols); c ) {
let cell = document.createElement("div");
cell.classes = ['grid-item'];
cell.style.setProperty('height', '24px');
cell.style.setProperty('background-color', 'black');
container.appendChild(cell).className = "grid-item";
};
};
makeRows(16, 16);
function changeGridColor (e) {
e.style.backgroundColor="red";
};
document.addEventListener('click',function(e){
console.log(e.target.classes);
if(e.target && e.target.classes.includes('grid-item')){
changeGridColor(e.target);
}
});
We add the grid-item
class and then setup a click event listener so that whenever a grid item class is clicked, the color is changed.
Here's a working jsfiddle: https://jsfiddle.net/1e7c2gzu/22/
(Also note you wouldn't see your grid items initially because they didn't have a size to them so I added a size and set them to black so you could see them)