0

I have a drop down menu with the visibility set to hidden. When the list element containing the drop down menu is clicked, javascript is supposed to add a class where the visibility is set to visible. The problem is, is that when I click on the list element, the visibility property is only changed for a fraction of a second, and then reverts back to hidden. How to I make it so that when the list element is clicked, the drop down unordered list stays visible until the next click?

document.querySelector('#drop').addEventListener('click', (e) => {
    document.querySelector('.sub-men').classList.toggle('visible');
})
  
    
* {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

nav {
    display: flex;
    flex-direction: row;
    justify-content: space-between;
    height: 10vh;
    background-color: aquamarine;
}
.logo {
    display: flex;
    align-items: center;
    margin-left: 10px;
}

.main-menu {
    display: flex;
    list-style: none;
    align-items: center;
}

.main-menu > li {
    position: relative;
    height: 10vh;

    
}

.main-menu > li > a {
    display: flex;
    padding: 0 1rem;
    text-decoration: none;
    background-color: antiquewhite;
    height: 10vh;
    align-items: center;
}

.sub-men {
    display: flex;
    flex-direction: column;
    position: absolute;
    list-style: none;
    visibility: hidden;
    
}

.sub-men > li {
    position: relative;
    background-color: aquamarine;
    padding: .5rem 1rem;
    width: 100px;
    text-align: center;
    
}

.visible {
    visibility: visible;
}

.sub-men > li:hover {
    background-color: aqua;
}

.sub-men > li > a {
    text-decoration: none;
    position: relative;
   
}
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>HTML 5 Boilerplate</title>
    <link rel="stylesheet" href="styles.css">
    <script src="jquery-3.6.0.min.js"></script>
  </head>
  <body>
    <nav>
        <h1 class="logo">Logo</h1>
        <ul class="main-menu">
            <li><a href="">Link 1</a></li>
            <li><a href="" id="drop">Link 2</a>
            <ul class="sub-men">
                <li><a href="">Sub-1</a></li>
                <li><a href="">Sub-1</a></li>
                <li><a href="">Sub-1</a></li>
            </ul>
            </li>
            <li><a href="">Link 3</a></li>
        </ul>
    </nav>
    <script src="index.js"></script>
  </body>
</html>
Brian
  • 87
  • 1
  • 5
  • 1
    You need to prevent the default action when that click event occurs. Add `e.preventDefault();` before setting your classlist toggle. Also see https://stackoverflow.com/questions/4855168/what-is-href-and-why-is-it-used for when and why `href="javascript:void(0);"` should be used. – Lucretius Jun 20 '22 at 20:43

1 Answers1

0

You can do this with CSS only, but it haves no keyboard accessible navigation

Just remove your js and add .main-menu li:hover .sub-men {visibility: visible;} to your css. (Tested it with multiple drop downs)

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

nav {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  height: 10vh;
  background-color: aquamarine;
}

.logo {
  display: flex;
  align-items: center;
  margin-left: 10px;
}

.main-menu {
  display: flex;
  list-style: none;
  align-items: center;
}

.main-menu>li {
  position: relative;
  height: 10vh;
}

.main-menu>li>a {
  display: flex;
  padding: 0 1rem;
  text-decoration: none;
  background-color: antiquewhite;
  height: 10vh;
  align-items: center;
}

.sub-men {
  display: flex;
  flex-direction: column;
  position: absolute;
  list-style: none;
  visibility: hidden;
}

/* makes sub-men visible when its parent is hoverd. */
.main-menu li:hover .sub-men {
  visibility: visible;
}

.sub-men>li {
  position: relative;
  background-color: aquamarine;
  padding: .5rem 1rem;
  width: 100px;
  text-align: center;
}

.visible {
  visibility: visible;
}

.sub-men>li:hover {
  background-color: aqua;
}

.sub-men>li>a {
  text-decoration: none;
  position: relative;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>HTML 5 Boilerplate</title>
  <link rel="stylesheet" href="styles.css">
  <script src="jquery-3.6.0.min.js"></script>
</head>

<body>
  <nav>
    <h1 class="logo">Logo</h1>
    <ul class="main-menu">
      <li><a href="">Link 1</a></li>
      <li><a href="" id="drop">Link 2</a>
        <ul class="sub-men">
          <li><a href="">Sub-1</a></li>
          <li><a href="">Sub-1</a></li>
          <li><a href="">Sub-1</a></li>
        </ul>
      </li>
      <li><a href="">Link 3</a></li>
    </ul>
  </nav>
  <script src="index.js"></script>
</body>

</html>
Drahcir
  • 19
  • 6