Reputation: 377
I am making an etch-a-sketch and I am trying to use an addEventListener event of 'mouseover' to add a CSS class where the background of the square the mouse hovers over will turn black. I have a function that creates a single box and if I put the event listener inside this function it works, however if I try to do it outside the function it doesn't work
The function box creates a single box (which will get repeated using the addMultipleBox function) and adds a mouseover event. In this scenario the mouseover works correctly
function box() {
let square = document.createElement('div')
square.setAttribute('class', 'box')
container.appendChild(square)
square.addEventListener('mouseover', () => {
square.classList.add('blackPen')
})
}
//creates the etch a sketch board with multiple 'boxes'
function addMultipleBoxes() {
for(let i = 0; i < 256; i++) {
box()
}
}
Now if I try and grab the class of 'box' outside the function and add an event listener to it nothing happens. I do have this code at the bottom so it's not like i'm trying to grab divs before they are created.
I'd like to be able to grab it outside so I can create another function that on a mouse click I remove the class of 'blackPen' which will remove the background color of black on the square, essentially wiping the board clean. Here is what I have for that
let boxx = document.querySelector('.box')
console.log(boxx)
boxx.addEventListener('mouseover', () => {
boxx.classList.add('blackPen')
})
When I console.log 'Boxx' I get the <div class="box"></div>
. If I console.log "square" above in the box function I get the same thing as Boxx.
Any insight would be much appreciated!
Upvotes: 0
Views: 2694
Reputation: 2687
The box()
function adds the class to each element as it is made, as required.
A reference made to an element using querySelector
contains only one element - the first in the document with the specified selector. See https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector
This snippet illustrates the idea with four divs, all the same class.
let boxx = document.querySelector('.box')
boxx.addEventListener('mouseover', () => {
boxx.classList.add('blackPen')
})
.box {
display: inline-block;
width: 70px;
aspect-ratio: 1;
background: yellow;
border: 1px solid red;
}
.blackPen {
background: black;
}
<p><b>mouseover applied to element got by querySelector</b></p>
<p>(move mouse over divs)</d>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<p>querySelector, returns the <em>first</em> Element within the document that matches the specified selector</p>
A reference to all elements with a given class can be made using querySelectorAll()
, which returns a live node list with references to all the elements of the given selector. See: https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll
Having made the reference, you will still have to loop through them in order to add the event listeners required. node lists and html collections are array-like structures that can have individual members referenced by and index [0]
,[1]
, and so on.
This snippet illustrates adding a new class to each div in a node list formed using querySelectorAll:
let boxx = document.querySelectorAll('.box')
for (let i=0; i<boxx.length; i++) {
boxx[i].addEventListener('mouseover', () => {
boxx[i].classList.add('blackPen');
boxx[i].classList.remove('cancel');
});
boxx[i].addEventListener('click', () => {
boxx[i].classList.add('cancel')
});
} // next i boxx element;
.box {
display: inline-block;
width: 70px;
aspect-ratio: 1;
background: yellow;
border: 1px solid red;
}
.blackPen {
background: black;
}
.cancel {
background: yellow;
}
<p><b>mouseover applied to all elements got by querySelectorAll</b><br>(move mouse over divs)</d>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<p>A click event was also added to all elements, to replace the class added by the mouseover event<br>click boxes to see the effect</p>
Note that the node collection only needs to be made once to be used for any further manipulations. In the snippet a mouseover event adds a class to make the background black while a click event cancels it.
Upvotes: 0