I am completing the "etch-a-sketch" challenge as part of TOP curriculum. I have successfully created a 16 x 16 grid utilizing JS DOM manipulation and CSS grid. The second part of my problem is to make each individual grid-item/cell change background color on hover. I chose to use JS with the mouseover Eventlistener, but also saw the CSS: hover Selector as a viable option when googling for information.
I have created 2 functions overing
and outing
to change the background color of the grid-item on hover using the "mouseover" event listener. The functions only work on the first generated cell/grid-item. May someone please explain how I can get my overing and outing functions to work on all grid-items.only 1st grid-item working
//Function and call to generate 16x16 grid of divs.
document.getElementById("container");
function makeGrid(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.innerText = (c + 1);
container.appendChild(cell).className = "grid-item";
};
};
makeGrid(16, 16);
//Function to change background color of individual "grid-item" on hover.
document.querySelector('.grid-item').addEventListener('mouseover', overing);
document.querySelector('.grid-item').addEventListener('mouseout', outing);
function overing(ev) {
ev.currentTarget.style.backgroundColor = 'red';
console.log('mouseenter div');
}
function outing(ev) {
ev.currentTarget.style.backgroundColor = 'white';
console.log('mouseleave div');
}
:root {
--grid-cols: 1;
--grid-rows: 1;
}
#container {
display: grid;
grid-gap: 1em;
grid-template-columns: repeat(var(--grid-cols), 1fr);
grid-template-rows: repeat(var(--grid-rows), 1fr);
}
.grid-item {
padding: 1em;
border: 1px solid black;
text-align: center;
}
<!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>Sketch-Book</title>
<link rel="stylesheet" type="text/css" href="etchStyles.css" />
</head>
<body>
<div id="container">
</div>
</body>
<script type="text/javascript" src="etchScript.js"></script>
</html>
3
Answers
@Titus is right. But since you are using javascript to create each DOM node, you can exploit this fact to attach event listeners at creation time. Ex:
You could use css
:hover
, here is an example with a 3×3 grid:All modern browsers support template ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template so lets’ use that instead of manually creating an element so out code can be smaller – especially if you add more content to each "cell" such as a set of spans, divs etc.
You can determine what you want for event handlers but you can add those right in the same loop when creating them.
NOTE: Probably want to create a new DIV just to append all the NEW items to before hitting the DOM and appending them all at once but I will leave that exercise to you as outside the question scope.