hailexe
hailexe

Reputation: 19

Adding event listeners to an array of elements using forEach

I created nine blue div boxes and I'm trying to write a Javascript that will set the opacity of each box to 0 once the box is hovered over. I made an array of all the boxes but when I try to apply addEventListener to each array element using forEach method it returns "Cannot set properties of undefined" error. What mistake am I making?

const boxes=document.getElementsByClassName("box");
const arrayOfBoxes=Array.from(boxes);
arrayOfBoxes.forEach((box)=>{box.addEventListener("mouseover",hide)});

function hide(element){
    element.style.opacity=0.0;
}
<div class="boxes">
    <div class="box" style="background-color: blue; height:100px; width:100px; margin: 5px"></div>
    <div class="box" style="background-color: blue; height:100px; width:100px; margin: 5px"></div>
    <div class="box" style="background-color: blue; height:100px; width:100px; margin: 5px"></div>
    <div class="box" style="background-color: blue; height:100px; width:100px; margin: 5px"></div>
    <div class="box" style="background-color: blue; height:100px; width:100px; margin: 5px"></div>
    <div class="box" style="background-color: blue; height:100px; width:100px; margin: 5px"></div>
    <div class="box" style="background-color: blue; height:100px; width:100px; margin: 5px"></div>
    <div class="box" style="background-color: blue; height:100px; width:100px; margin: 5px"></div>
    <div class="box" style="background-color: blue; height:100px; width:100px; margin: 5px"></div>
</div>

Upvotes: 0

Views: 982

Answers (4)

zer00ne
zer00ne

Reputation: 44086

There's three ways to identify the actual tag a user has interacted with:

//.target property points to the tag the user interacted with
event.target.style.opacity = '0.0';

/*
.currentTarget property points to the tag that the event listener is attached to.
*/
event.currentTarget.style.opacity = '0.0';

/*
"this" a keyword that points to an object. If "this" is in an event handler, it
will point to the same thing .currentTarget points to.
*/
this.style.opacity ="0.0"

Also, the event handler passes the event object by default, so when you passed element, it was considered the event object. In order not to confuse anyone that happens to read your code, choose a more accurate moniker like: event, e, evt, etc.

const boxes=document.getElementsByClassName("box");
const arrayOfBoxes=Array.from(boxes);
arrayOfBoxes.forEach((box)=>{box.addEventListener("mouseover",hide)});

function hide(event) {
    this.style.opacity=0.0;
}
<div class="boxes">
    <div class="box" style="background-color: blue; height:100px; width:100px; margin: 5px"></div>
    <div class="box" style="background-color: blue; height:100px; width:100px; margin: 5px"></div>
    <div class="box" style="background-color: blue; height:100px; width:100px; margin: 5px"></div>
    <div class="box" style="background-color: blue; height:100px; width:100px; margin: 5px"></div>
    <div class="box" style="background-color: blue; height:100px; width:100px; margin: 5px"></div>
    <div class="box" style="background-color: blue; height:100px; width:100px; margin: 5px"></div>
    <div class="box" style="background-color: blue; height:100px; width:100px; margin: 5px"></div>
    <div class="box" style="background-color: blue; height:100px; width:100px; margin: 5px"></div>
    <div class="box" style="background-color: blue; height:100px; width:100px; margin: 5px"></div>
</div>

Upvotes: 0

mstephen19
mstephen19

Reputation: 1926

Instead of adding an event listener to every single div (which can cause problems as the number of divs likely increases), just add one event listener to the parent element that listens for the 'mouseover' event to achieve the same exact goal.

const boxes = document.querySelector('div.boxes');

const handleHover = (e) => {
    if (e.target === boxes) return;
    e.target.style.opacity = 0;
};

boxes.addEventListener('mouseover', handleHover);
<div class="boxes" style="display: flex; flex-direction: column; gap: 10px">
    <div class="box" style="background-color: blue; height: 100px; width: 100px"></div>
    <div class="box" style="background-color: blue; height: 100px; width: 100px"></div>
    <div class="box" style="background-color: blue; height: 100px; width: 100px"></div>
    <div class="box" style="background-color: blue; height: 100px; width: 100px"></div>
    <div class="box" style="background-color: blue; height: 100px; width: 100px"></div>
    <div class="box" style="background-color: blue; height: 100px; width: 100px"></div>
    <div class="box" style="background-color: blue; height: 100px; width: 100px"></div>
    <div class="box" style="background-color: blue; height: 100px; width: 100px"></div>
    <div class="box" style="background-color: blue; height: 100px; width: 100px"></div>
</div>

Upvotes: 0

Barmar
Barmar

Reputation: 782653

The argument to an event listener is the event, not the element. So use event.currentTarget to get the element.

function hide(event){
    event.currentTarget.style.opacity=0.0;
}

Upvotes: 1

IT goldman
IT goldman

Reputation: 19521

Did you know you could achieve this using CSS only?

.box {
  opacity: 1;
  transition: 250ms all;
  float: left;
}

.box:hover {
  opacity: 0;
}
<div class="boxes">
  <div class="box" style="background-color: blue; height:100px; width:100px; margin: 5px"></div>
  <div class="box" style="background-color: blue; height:100px; width:100px; margin: 5px"></div>
  <div class="box" style="background-color: blue; height:100px; width:100px; margin: 5px"></div>
  <div class="box" style="background-color: blue; height:100px; width:100px; margin: 5px"></div>
  <div class="box" style="background-color: blue; height:100px; width:100px; margin: 5px"></div>
  <div class="box" style="background-color: blue; height:100px; width:100px; margin: 5px"></div>
  <div class="box" style="background-color: blue; height:100px; width:100px; margin: 5px"></div>
  <div class="box" style="background-color: blue; height:100px; width:100px; margin: 5px"></div>
  <div class="box" style="background-color: blue; height:100px; width:100px; margin: 5px"></div>
</div>

Upvotes: 1

Related Questions