How to make addEventListener ‘click’ work on two menu items with same class

Page: https://ensjotannklinikk.no/forside-wip

Here’s a fiddle

The first menu item called “Behandlinger” is set up with this JS (couertesy of biberman) to make the sub menu emerge and retract properly.

var submenu = document.querySelector('.behandlinger-meny');
var menuTrigger = document.querySelector('.behandlinger-item');

//javascript version of jQuery isChild()
function isChild(item, parentItem) {
    while (item != undefined && item != null && item.tagName.toUpperCase() != 'BODY'){
        if (item == parentItem){
            return true;
        }
        item = item.parentNode;
    }
    return false;
}

menuTrigger.addEventListener('click', function() {
    submenu.style.height = '55px';
});

document.querySelector('body').addEventListener('click', function(e) {
    if ( !isChild(e.target, menuTrigger) && !isChild(e.target, submenu) ) {
        submenu.style.height = 0;
    }
});

document.addEventListener('keyup', function(e) {
    if ( e.key == 'Escape' ) {
        submenu.style.height = 0;
    }
});

Why is this not working on mobile? I wish for the submenu (.behandlinger-meny) height set to 55px when the menu item Behandlinger (.behandlinger-item) is clicked. It workes pefectly, except not on the menu item click on mobile.

Update 1 Realized the mobile menu has a <nav> of it’s own, which may affect the event listener. I have updated both the fiddle and the simplified structure below as well as the core question. Seems really close to a simple solution now.

Simplified structure:

.behandlinger-meny {
    height: 0;
    transition: all .3s cubic-bezier(0.4, 0.0, 0.2, 1);
    overflow: hidden;
}
<div id="wrapper">
  <header>

    <nav class="main-menu">
      <ul>
        <li class="behandlinger-item"><a href="#behandlinger">Behandlinger</a></li>
        <li><a>Item 2</a></li>
        <li><a>Item 3</a></li>
        <li><a>Item 4</a></li>
      </ul>
    </nav>

    <nav class="mobile-main-menu">
      <ul>
        <li class="mobile-item behandlinger-item"><a href="#behandlinger">Behandlinger</a></li>
        <li><a>Item 2</a></li>
        <li><a>Item 3</a></li>
        <li><a>Item 4</a></li>
      </ul>
    </nav>

  </header>

  <section> <!-- Separated to follow page scroll -->
    <div id="behandlinger"> <!-- Scroll to position on item click -->
      <nav class="behandlinger-meny">
        <script></script> <!-- Script in question  -->
        <ul>
          <li><a>Sub item 1</a></li>
          <li><a>Sub item 2</a></li>
          <li><a>Sub item 3</a></li>
        </ul>
      </nav>
    </div>
  </section>

  <main>
    …
  </main>
</div>

Answer

Since you have two triggers and your event listener is only attached to the first with querySelector the second trigger has no listener.

You can use querySelectorAll and attach the event listener in a for loop to each selected trigger. Because you want a transition you have to use ‘max-height’ instead of ‘height’ since transition doesn’t work with height.

For closing the submenu when clicking somewhere else (except trigger or submenu) i made a function isRelated() that checks if the click target is the trigger itself, the submenu or a child of both.

Working example with multiple triggers:

document.addEventListener('DOMContentLoaded', function() {

  var submenu = document.querySelector('.behandlinger-meny');
  var menuTrigger = document.querySelectorAll('.behandlinger-item');

  function isRelated(item, parentSelector) {
    while (item != undefined && item != null && item.tagName.toUpperCase() != 'BODY') {
      parents = document.querySelectorAll(parentSelector);
      for (i = 0; i < parents.length; i++) {
        if (item == parents[i]) {
          return true;
        }
      }
      item = item.parentNode;
    }
    return false;
  }

  for (i = 0; i < menuTrigger.length; i++) {
    menuTrigger[i].addEventListener('click', function() {
      submenu.style.maxHeight = '1000px';
    });
  }

  document.querySelector('body').addEventListener('click', function(e) {
    if (!isRelated(e.target, '.behandlinger-item') && !isRelated(e.target, '.behandlinger-meny')) {
      submenu.style.maxHeight = 0;
    }
  });

  document.addEventListener('keyup', function(e) {
    if (e.key == 'Escape') {
      submenu.style.maxHeight = 0;
    }
  });

});
header {
  display: flex;
}

.behandlinger-meny {
  max-height: 0;
  width: 150px;
  background-color: #ddd;
  transition: all .3s cubic-bezier(0.4, 0.0, 0.2, 1);
  overflow: hidden;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div id="wrapper">

  <header>
    <nav class="main-menu">
      <ul>
        <li class="behandlinger-item"><a href="#behandlinger">Behandlinger</a></li>
        <li><a>Item 2</a></li>
        <li><a>Item 3</a></li>
        <li><a>Item 4</a></li>
      </ul>
    </nav>

    <nav class="mobile-main-menu">
      <ul>
        <li class="mobile-item behandlinger-item"><a href="#behandlinger">Behandlinger</a></li>
        <li><a>Item 2</a></li>
        <li><a>Item 3</a></li>
        <li><a>Item 4</a></li>
      </ul>
    </nav>
  </header>

  <section>
    <div id="behandlinger">
      <nav class="behandlinger-meny">
        <ul>
          <li><a>Sub item 1</a></li>
          <li><a>Sub item 2</a></li>
          <li><a>Sub item 3</a></li>
        </ul>
      </nav>
    </div>
  </section>

  <main>
    …
  </main>

</div>