# Handling events for many elements tutorial: is this always the best approach?

**URL:** <https://forum.kirupa.com/t/handling-events-for-many-elements-tutorial-is-this-always-the-best-approach/652188>\
**Category:** web dev\
**Created:** [June 10, 2022, 3:34pm UTC](https://forum.kirupa.com/t/handling-events-for-many-elements-tutorial-is-this-always-the-best-approach/652188 "2022-06-10T15:34:33Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Daave](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/daave/32/17911_2.png) [@Daave](https://forum.kirupa.com/u/Daave)\
**Post date:** [June 10, 2022, 3:34pm UTC](https://forum.kirupa.com/t/handling-events-for-many-elements-tutorial-is-this-always-the-best-approach/652188/1 "2022-06-10T15:34:33Z")

</div>

I would like to share my thoughts (and very little experience), as a junior web developer, on Kirupa’s very interesting tutorial “Handling events for many elements”. I tried using it in a project I am currently working on (as a student enrolled in a JavaScript/React online course). I’m basically building an image slider that opens when you click any of the images in a gallery. Following Kirupa’s idea, I added an event listener to the closest common ancestor of my image elements (or the div that serves as a container for my images rather), which happens to be the div that contains my entire image gallery. So I have another div element between that ancestor and my “div.image” elements. Therefore, I end up with intermediary elements which also have that event listener on them when they absolutely do not need it. It even creates a bug when I click slightly below an image in the gallery because I am targeting an element that should not be listening to the click event. So I was wondering whether Kirupa’s solution is adequate in case there are other descendents in between the common ancestor and the elements we want to add the event listeners to. I’d be interested to have other developers’ view on this. As I mentioned above, I am a JavaScript beginner, so any advice from more experienced developers would be much appreciated. 😃

Below is the code that deals with listening and reacting to the click event:

```auto
// Handle click event on media elements
const handleClickOnMedia = ($event) => {
  let clickedItemParentId;
  if ($event.target !== $event.currentTarget) {
  clickedItemParentId = $event.target.parentElement.id;
  openLightbox(clickedItemParentId);
  }
  $event.stopPropagation();

  return clickedItemParentId;
};

// We target the nearest common ancestor of all media elements
const mediaCommonAncestor = document.querySelector('.photographer__portfolio-images');
// We can then add an event listener on that element
// instead of adding multiple event listeners on all media elements
mediaCommonAncestor.addEventListener('click', handleClickOnMedia);

```

And this is the structure of my HTML:

 ![Screen Shot 2022-06-10 at 18.00.09](https://canada1.discourse-cdn.com/flex011/uploads/kirupa/original/3X/8/7/87546ac845c8b100a5c4caab97f2f8c7ee32dc6e.png)

---

<div class="post-metadata">

**Author:** ![steve.mills](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/steve.mills/32/14961_2.png) [@steve.mills](https://forum.kirupa.com/u/steve.mills)\
**Post date:** [June 10, 2022, 11:04pm UTC](https://forum.kirupa.com/t/handling-events-for-many-elements-tutorial-is-this-always-the-best-approach/652188/2 "2022-06-10T23:04:52Z")

</div>

What your getting is pointer events from the parent element.

There’s 2 ways to deal with it and its good practice to use both.

**Pointer events: none**

- set all elements in your CSS as `*{pointer-events: none}`
- create a CSS selector that targets every element that you want click events from
  - e.g `.clickable{pointer-events: auto}`
  - or `button, input, select{pointer-events: auto}`

**Default return function**

- set your events as a data-set attribute to the DOM node e.g.
  - `<div` **data-event = “openLightbox”** `class = "clickable" >Image</div>`…

- access the event like `e.target.dataset.event` (`"openLightbox"`)
- run/ access the desired function as a property of an object (`openLightbox` is now the object method… `events.openLightbox` )
- have a fallback function (`no_event`) for when you have forgotten to add an attribute (`data-event = "open_lightbox"`) to the element as above

e.g.

```auto
const events = {
    no_event: function(){return console.log("no event attached")},
    openLightbox: function(e){
      parent_id = e.target.parentElement.id;
 //run some code
    }
}

```

```auto
const listenHandler = function(e){
  if(e.target === e.currentTarget) return
  let run = events[e.target.dataset.event] || events["no_event"];
e.stopPropogation()
  return run(e)
}

```

FYI you can just add an `eventListener()` and an `event object` (all your event functions in one object) for an entire page **IF** there’s no `shadow DOM`.

And also… you don’t have to use `div` all over your page.

There are elements that are semantic e.g. `<nav> <a> <button>` **but** `<div>` and `<span>` mean nothing to the browser without e.g. `role = "navigation"`.

If you have an undefined `customElement` e.g.`<portfolio-carousel>` (not registered with e.g `customElements.define("portfolio-carousel", portf_carousel)`… then the browser will treat it as a `<div>` by default…

something like this is way more readable than `<div>` soup:

```auto
<portfolio-carousel>
    <image-card>
        <frame-16-9>
            <img src="" alt="">
        </frame-16-9>
    </image-card>
    <image-card>
        <frame-16-9>
            <img src="" alt="">
        </frame-16-9>
    </image-card>
</portfolio-carousel>

```

You can also use more CSS selectors e.g  
`frame-16-9 { aspect-ratio: 16 / 9;}`

instead of class soup like Tail Wind…

Is it just me or does the words “tail wind” immediately bring to mind a fart… 😆

I hope this helps 🙂

---

<div class="post-metadata">

**Author:** ![steve.mills](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/steve.mills/32/14961_2.png) [@steve.mills](https://forum.kirupa.com/u/steve.mills)\
**Post date:** [June 11, 2022, 12:06am UTC](https://forum.kirupa.com/t/handling-events-for-many-elements-tutorial-is-this-always-the-best-approach/652188/3 "2022-06-11T00:06:20Z")

</div>

Also having all your event functions in an object makes it super easy to add a `finite state machine`…

Finite state machines are the most robust way to handle state… The Mars rover used nested FSM (hierarchical state machines)…

> **[Hierarchical State Machines on Mars](https://www.state-machine.com/hierarchical-state-machines-persevere-on-mars)**
>
> The role of Hierarchical State Machines in the Mars Perseverance rover explained by the NASA's JPL flight control software technical lead Steve Scandore.

Xstate is the well known one for JS…

---

<div class="post-metadata">

**Author:** ![Daave](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/daave/32/17911_2.png) [@Daave](https://forum.kirupa.com/u/Daave)\
**Post date:** [June 11, 2022, 3:39pm UTC](https://forum.kirupa.com/t/handling-events-for-many-elements-tutorial-is-this-always-the-best-approach/652188/4 "2022-06-11T15:39:23Z")

</div>

Thanks a lot for your very detailed answer! Lots of new stuff for me here. The only thing I knew about was the div soup you’re supposed to avoid, which I do as best I can. I just feel that once you’ve used all the semantic tags you’re supposed to and find yourself deep inside your HTML structure there’s not much you can do about it. I had no clue you could create your own custom HTML tags. I mean, really, what have they been teaching me?!

I had never thought of Tailwind as a potential gas hazard but now that you mention it… 😄

Ok I’m off to put all the new stuff to the practice. I’ll let you know how it worked out. 😉

---

<div class="post-metadata">

**Author:** ![Daave](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/daave/32/17911_2.png) [@Daave](https://forum.kirupa.com/u/Daave)\
**Post date:** [June 11, 2022, 3:43pm UTC](https://forum.kirupa.com/t/handling-events-for-many-elements-tutorial-is-this-always-the-best-approach/652188/5 "2022-06-11T15:43:16Z")

</div>

And thanks for sharing the blog post about hierarchical state machines. More new stuff for me to reflect on… 😃
