let container =
document.getElementById('container');
function getGrid(gridNumber) {
for (let i = 1; i <= gridNumber * gridNumber; i ) {
const row = document.createElement('div');
row.style.border = '1px solid red'
container.appendChild(row).classList.add('box');
}
}
getGrid(16);
.banner {
display: flex;
justify-content: center;
}
.divcontainer {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
#container {
margin-top: 100px;
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr;
}
.box {
height: 20px;
width: 20px;
}
<div >
<div >
<h1> Etch-a-Sketch </h1>
</div>
</div>
<div >
<div id="container"></div>
</div>
I am making a simple etech a sketch and so far i have created a grid of square divs. i need some direction on where to go from here. i think i need to attach keydown event listeners of each of the divs that i injected using javascript dom manipulation but how do i add event listeners to divs injected?
CodePudding user response:
You can add event listeners to an HTMLElement at any time after you create it, as long as you keep a reference to it, in this case the variable row
const row = document.createElement('div');
row.addEventListener('click', event=>{
//... Reaction ...
})
CodePudding user response:
Use event-delegation. This means adding a single event listener that capture the events that bubble. In there check if the clicked element is the element you're expecting it to be.
const container = document.getElementById('container');
container.addEventListener('click', event => {
const isbox = event.target.closest('.box') !== null;
if (!isBox) {
// Not a box, do nothing.
return;
}
// Assert logic
});
CodePudding user response:
I am not sure if this is the behavior you want but you can add event on row directly (I've put a condition in case you want to 'uncolor' the selected box)
let container =
document.getElementById('container');
function getGrid(gridNumber) {
for (let i = 1; i <= gridNumber * gridNumber; i ) {
const row = document.createElement('div');
row.style.border = '1px solid red'
container.appendChild(row).classList.add('box');
row.addEventListener('click', function(event) {
if (row.style.background === 'green')
row.style.background = 'none'
else
row.style.background = 'green'
});
}
}
getGrid(16);
.banner {
display: flex;
justify-content: center;
}
.divcontainer {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
#container {
margin-top: 100px;
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr;
}
.box {
height: 20px;
width: 20px;
}
<div >
<div >
<h1> Etch-a-Sketch </h1>
</div>
</div>
<div >
<div id="container"></div>
</div>
CodePudding user response:
Event delegation is the best solution for this. Instead of adding listeners to all the grid squares add one to the parent element and have that watch for events from its child elements as they "bubble up" the DOM.
When the listener captures an event it first checks to see if the element that triggered it is a box (it might have other child elements that aren't boxes that we want to ignore), and then it executes some code - in this case it toggles a filled
class on the box.
(I've played around a little with your CSS in this expanded example, and renamed a couple of ids/classes in the HTML.)
// Cache the grid element, and add a listener to it
const grid = document.querySelector('.grid');
grid.addEventListener('click', handleClick);
function getGrid(gridNumber) {
for (let i = 1; i <= gridNumber * gridNumber; i ) {
const box = document.createElement('div');
// Renamed the variable, and added the border
// color to CSS instead
box.classList.add('box');
grid.appendChild(box);
}
}
getGrid(16);
// When an element is clicked the listener (attached
// to the `.grid` parent element) checks that that
// it was a box, and then toggles a `filled` class on
// that clicked element
function handleClick(e) {
if (e.target.matches('.box')) {
e.target.classList.toggle('filled');
}
}
.banner {
display: flex;
justify-content: center;
}
.container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
margin: 0 0 2em 0;
}
.grid {
display: grid;
grid-template-columns: repeat(16, 1fr);
}
.box {
height: 20px;
width: 20px;
border: 1px solid red;
}
.box:hover { cursor: pointer; }
.box:hover:not(.filled) { background-color: red; opacity: 0.3; }
.filled { background-color: red; }
<div >
<div >
<h1> Etch-a-Sketch </h1>
</div>
</div>
<div >
<div ></div>
</div>