I'm making an Etch-a-Sketch. I currently have a set amount of divs. Each one of them share a class and event listener. I used a for each function, so that they all follow the same event. When I click any of my divs, all of them will turn blue. I want for the one div that I click to turn blue instead of all of them at the same time. Here is my code, what can I do so that The item I click changes, instead of all of the items changing.
function makeRows(rows, cols){
for (let i = 0; i < (rows * cols); i++){
let container= document.getElementById("container");
let cell= document.createElement("div");
cell.innerText = (i + 1);
cell.setAttribute('id','box');
container.appendChild(cell).className = "box";
}
};
makeRows(16,16);
//events
document.querySelectorAll('.box').forEach(box => {
box.setAttribute("style", "background-color: red;");
});
document.addEventListener('click', changeColor);
function changeColor(){
document.querySelectorAll('.box').forEach(box => {
box.setAttribute("style", "background-color:blue ;");
});
}
You are using event delegation so you need to look at what was clicked. You can do that with event target.
function makeRows(rows, cols) {
for (let i = 0; i < (rows * cols); i++) {
let container = document.getElementById("container");
let cell = document.createElement("div");
cell.innerText = (i + 1);
// cell.setAttribute('id', 'box'); useless
container.appendChild(cell).className = "box";
}
};
makeRows(16, 16);
document.addEventListener('click', changeColor);
function changeColor(evt) {
const box = evt.target.closest(".box");
if (box) {
box.classList.toggle("selected");
}
}
.box {
width: 50px;
height: 50px;
display: inline-block;
}
.box.selected {
background-color: blue;
}
<div id="container"></div>
Right now you're adding an event listener to the entire document.
document.addEventListener('click', changeColor);
When you click on the document, it will trigger your changeColor() function which loops through each box and turns them all blue.
What you want is that each BOX has it's own event listener, that when clicked on it will change it's own color.
Now it becomes clear:
document.querySelectorAll('.box').forEach(box => {
box.addEventListener("click", ()=>{
box.setAttribute("style", "background-color:blue ;");
}
});
For each box, give that box it's own event listner. On click, change the style.
Albeit it, epascarello's answer is MUCH better than mine, but I hope the logic makes sense.