Javascript newbie following Ania Kubow’s Javascript bootcamp video / card matching game tutorial (https://youtu.be/Xm4BObh4MhI?t=34702).
I’d like to request some help figuring out how to have an image change when hovered over, specifically within the Javascript code. For context, I’m making a card matching game based on the tutorial above, except it’s Pokemon themed. When the card/open Pokeball is hovered over, it should then change to a half-way closed Pokeball to show that it’s almost selected.
What’s in the HTML file in this section is literally just:
<div class="section2"></div>
So it’s all in the Javascript where all of this comes from. Here is the main function. (Bolded is what I added myself.
function createBoard() {
for (let i = 0; i < cardArray.length; i++) {
const card = document.createElement('img')
card.setAttribute('src', 'src/images/pokeballOpen.png')
card.setAttribute('data-id', i)
card.addEventListener('click', flipCard)
** card.addEventListener('mouseover', hoverPokeball)
card.addEventListener('mouseout', unhoverPokeball)**
container.appendChild(card)
}
}
Then I also have:
function hoverPokeball() {
card.setAttribute('src', 'src/images/pokeballMid.png')
}
// unhover over pokeball
function unhoverPokeball() {
card.setAttribute('src', 'src/images/pokeballOpen.png')
}
I am 100% missing something simple here, and I would appreciate it if any of you could help me out.
2
Answers
Use
event.target
to access the<img>
element being hovered.The functions
hoverPokeball
andunhoverPokeball
are not defined in the same scope as thecard
variable, and can therefore not reference it. I presume you get aReferenceError
.There are multiple ways to reference the (un-)hovered element in its listener:
Passing the event object
You can pass the event object to the listener (or rather, expect it). Its
currentTarget
property will refer to the respectivecard
.Example:
Sidenote:
The
target
property refers to the the target from which the event is dispatched. ThecurrentTarget
property refers to the currently listening target, often a child of the dispatching target.In this case,
card
refers to an empty element; more specifically, to the void element<img>
. Such elements do not have children, so thecurrentTarget
andtarget
properties will refer to the same target.You should prefer the
currentTarget
andtarget
properties for the concepts of referring to the currently listening target and the dispatching target, respectively.In this case, we want to refer to
card
(the element to which we added the listener), so we should use thecurrentTarget
property. It just so happens thatcard
will always be the dispatching target as well due to it being an empty element.Passing the reference
Similarly, you can pass the reference
card
to the functions. This requires some kind of closure for the specific reference, e.g. by using an anonymous function defined in the respective iteration or binding the reference as an argument.Example of binding as an argument:
Using
this
in listenersIn listeners,
this
is bound to refer to the listening target. You can usethis
for the listening target, since the respectivecard
is that event target.Example:
Note: You cannot bind a
this
context to arrow function expressions. This means thathoverPokeball
andunhoverPokeball
have to be defined as function declarations or function expressions for this to work. Read more in MDN’s section aboutthis
in handlers.Alternatively, you can query for the element in the functions, e.g. by their
data-id
attribute.Generally, I would recommend to use event delegation for a task like this.