1

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 the btn.

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

user1941537
  • 6,097
  • 14
  • 52
  • 99
  • 1
    Possible duplicate of [Vanilla JS event delegation - dealing with child elements of the target element](https://stackoverflow.com/questions/24117369/vanilla-js-event-delegation-dealing-with-child-elements-of-the-target-element) – random_user_name Jul 08 '18 at 22:13

1 Answers1

6

Just add a listener to the .list-container instead, and on click, check to see if the target matches the .btn:

const detailsContainer = document.querySelector('.details');
document.querySelector('.list-container').addEventListener('click', ({ target }) => {
  if (target.matches('.btn')) detailsContainer.classList.toggle('visible');
});
.details { display: none }
.visible { display: block }
<div class='list-container'>container outside of button
  <button class="btn">More details </button>
</div>

<div class="details">Lorem ipsum lorem ipsum lorem ipsum</div>
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
  • Thanks for the solution, but if you have more than one item in your unordered list, this solution works only for the first item. – user1941537 Jul 09 '18 at 16:56
  • @user1941537 I don't understand, there are no lists (ordered nor unordered) in the HTML, neither in the answer nor in your question...? Of course, if the HTML is different, the Javascript would also have to be tweaked as well – CertainPerformance Jul 09 '18 at 19:36