6 Replies - 623 Views - Last Post: 09 July 2018 - 11:47 AM

#1 kayut   User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 55
  • Joined: 20-January 17

Event delegation with vanilla JS

Posted 08 July 2018 - 02:59 PM

Hi,

Based on the following HTML markup:

<div class='list-container'>
    <button class="btn">More details </button>
</div>

<div class="details">Lorem ipsum lorem ipsum lorem ipsum</div>


I wrote the following Javascript code:
let btn = document.querySelector('.btn');
let detailsContainer = document.querySelector('.details');

btn.addEventListener('click', function(e) {
  e.preventDefault();
  detailsContainer.classList.toggle('visible');
});


But I need to change the JS code to use the event delegation so that the eventListener gets added to the list-container instead of to btn.

It's easy in jQuery, but how can I do it in vanilla JS?

This post has been edited by kayut: 08 July 2018 - 03:01 PM


Is This A Good Question/Topic? 0
  • +

Replies To: Event delegation with vanilla JS

#2 Martyr2   User is offline

  • Programming Theoretician
  • member icon

Reputation: 5315
  • View blog
  • Posts: 14,185
  • Joined: 18-April 07

Re: Event delegation with vanilla JS

Posted 08 July 2018 - 04:04 PM

Instead of let btn = document.querySelector('.btn'); just use let container = document.querySelector('.list-container');. You then add the event listener to the parent. When the container's child elements are clicked, the event will bubble up to the parent, you can then analyze which element was clicked.

let container = document.querySelector('.list-container');
let detailsContainer = document.querySelector('.details');

container.addEventListener('click', function(e) {
  // Look at e.target to find out which child element was clicked (if you need to)
  e.preventDefault();
  detailsContainer.classList.toggle('visible');
});




I hope you get the idea. :)
Was This Post Helpful? 1
  • +
  • -

#3 Dormilich   User is offline

  • 痛覚残留
  • member icon

Reputation: 4221
  • View blog
  • Posts: 13,362
  • Joined: 08-June 10

Re: Event delegation with vanilla JS

Posted 09 July 2018 - 06:52 AM

Quote

Look at e.target to find out which child element was clicked

It's a bit more complicated than that. You would have to look if the target selector is an element between event.target and event.currentTarget (otherwise it won't work, if the desired element has child elements (e.g. a button with an icon inside)).

This post has been edited by Dormilich: 09 July 2018 - 06:53 AM

Was This Post Helpful? 0
  • +
  • -

#4 kayut   User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 55
  • Joined: 20-January 17

Re: Event delegation with vanilla JS

Posted 09 July 2018 - 09:58 AM

Thanks for the solution.

However, I just found out that if you have more than one item in your unordered list, this solution works only for the first item.

HTML
<ul id="container" class="cf">

<div class='list-container'>
    <button class="btn">More details </button>
</div>
<div class="details">Some text</div>

<div class='list-container'>
    <button class="btn">More details </button>
</div>
<div class="details">Another text</div>

<div class='list-container'>
    <button class="btn">More details </button>
</div>
<div class="details">More text</div>

</ul>


JS
  let container = document.querySelector('.list-container');
  let detailsContainer = document.querySelector('.details');

  container.addEventListener('click', function(e) {
    // Look at e.target to find out which child element was clicked (if you need to)
    e.preventDefault();
    if (e.target.matches('.btn')) {
      detailsContainer.classList.toggle('visible');
    }
  });


This post has been edited by kayut: 09 July 2018 - 10:07 AM

Was This Post Helpful? 0
  • +
  • -

#5 ArtificialSoldier   User is offline

  • D.I.C Lover
  • member icon

Reputation: 2187
  • View blog
  • Posts: 6,616
  • Joined: 15-January 14

Re: Event delegation with vanilla JS

Posted 09 July 2018 - 10:16 AM

Your unordered list has 0 items in it, so I would not expect that to work like you think it would. List items are <li> elements.

More importantly, your global variable detailsContainer never changes. You're always toggling the same element. You need to get any element you're going to change inside the event handler.
Was This Post Helpful? 0
  • +
  • -

#6 kayut   User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 55
  • Joined: 20-January 17

Re: Event delegation with vanilla JS

Posted 09 July 2018 - 11:38 AM

Quote

Your unordered list has 0 items in it

Sorry, I did a mistake. Those divs inside the UL should be LI.
Was This Post Helpful? 0
  • +
  • -

#7 ArtificialSoldier   User is offline

  • D.I.C Lover
  • member icon

Reputation: 2187
  • View blog
  • Posts: 6,616
  • Joined: 15-January 14

Re: Event delegation with vanilla JS

Posted 09 July 2018 - 11:47 AM

Do you understand what the issue is, though? Inside the event handler you're checking the event target, but you don't do anything with it.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1