Arthur Fortin
Arthur Fortin

Reputation: 181

Keep sub menu open on hover with javascript

Description : I got a nav bar with my menu and submenu. I use javascript to make the submenu appear on click

Here is my html

<ul class="menu grid-x">
  <div class="logo align-self-middle">
    <a href="#">LOGO</a>
  </div>
  <li class="item has-submenu align-self-middle grid-x align-middle">
    <a tabindex="0">Société</a>
    <ul class="submenu">
      <li class="subitem text-left"><a href="#">Présentation</a></li>
      <li class="subitem text-left"><a href="#">Nous rejoindre</a></li>
      <li class="subitem has-submenu text-left"><a tabindex="0">Nos agences</a></li>
      <li class="subitem text-left"><a href="#">Nos actualités</a></li>
    </ul>
  </li>
  <li class="item has-submenu align-self-middle">
    <a tabindex="0">Téléphonie</a>
    <ul class="submenu">
      <li class="subitem text-left"><a href="#">Téléphonie entreprise</a></li>
      <li class="subitem text-left"><a href="#">Flotte mobile</a></li>
      <li class="subitem text-left"><a href="#">Communications unifiées</a></li>
      <li class="subitem text-left"><a href="#">Centre de contact virtuel</a></li>
      <li class="subitem text-left"><a href="#">Centre de contact Multicanal</a></li>
    </ul>
  </li>
 <ul>

And here is the javascript I use

const items = document.querySelectorAll(".item");
const menu = document.querySelector(".menu");
 
/* Activate Submenu */
function toggleItem() {
  if (this.classList.contains("submenu-active")) {
    this.classList.remove("submenu-active");
  } else if (menu.querySelector(".submenu-active")) {
    menu.querySelector(".submenu-active").classList.remove("submenu-active");
    this.classList.add("submenu-active");
  } else {
    this.classList.add("submenu-active");
  }
}
 
/* Event Listeners */
for (let item of items) {
    if (item.querySelector(".submenu")) {
      item.addEventListener("click", toggleItem, false);
      item.addEventListener("keypress", toggleItem, false);
    }   
}

And the CSS to make the submenu appear when parent receive the submenu-active class

submenu-active .submenu {
    display: block;
    position: absolute;
    left: 0;
    top: 100%;
    min-width: 200px;
}

Problem : I would like to make the submenu appear on hover. The mouseover works when I hover the item class div, but submenu disappear when I try to click on one of its elements because I'm not maintaining the item div hover.

I don't want to use jquery and can't figure out a solution. Anyone could help ?

Thanks a lot

Upvotes: 0

Views: 1087

Answers (1)

GMKHussain
GMKHussain

Reputation: 4661

Try this code! and add style as you want.

You can include more mouse events add class on hover OR click is up to you.

const items = document.querySelectorAll(".item");
const menu = document.querySelector(".menu");
 
items.forEach(item => { 
   item.addEventListener('click', function() {
   
     if ( !item.classList.contains("show") ){
            item.classList.add("show")
        }else {
          item.classList.remove("show")
        }
  })
})
.has-submenu {
position: relative; }
.submenu {
display: none;
  background-color: #ffffff;
  position: absolute;
    left: 0;
    top: 100%;
    min-width: 200px;
    
  }
  
.has-submenu.show .submenu {
    display: block ;
  
}
<ul class="menu grid-x">
  <div class="logo align-self-middle">
    <a href="#">LOGO</a>
  </div>
  <li class="item has-submenu align-self-middle grid-x align-middle  ">
    <a tabindex="0">Société</a>
    <ul class="submenu ">
      <li class="subitem text-left"><a href="#">Présentation</a></li>
      <li class="subitem text-left"><a href="#">Nous rejoindre</a></li>
      <li class="subitem has-submenu text-left"><a tabindex="0">Nos agences</a></li>
      <li class="subitem text-left"><a href="#">Nos actualités</a></li>
    </ul>
  </li>
  <li class="item has-submenu align-self-middle">
    <a tabindex="0">Téléphonie</a>
    <ul class="submenu">
      <li class="subitem text-left"><a href="#">Téléphonie entreprise</a></li>
      <li class="subitem text-left"><a href="#">Flotte mobile</a></li>
      <li class="subitem text-left"><a href="#">Communications unifiées</a></li>
      <li class="subitem text-left"><a href="#">Centre de contact virtuel</a></li>
      <li class="subitem text-left"><a href="#">Centre de contact Multicanal</a></li>
    </ul>
  </li>
 <ul>

Upvotes: 1

Related Questions