0

So I am trying to use the same button to toggle on and off a side menu. However when I click the button nothing happens to the side menu. The code looks like it should work but I cannot figure out why it's not.

The menu should change height from 0 to 220px, the links from 0 to 1 opacity and from hidden to visible and the reverse when clocked again. But the only thing I can get to work is the hamburger animation on click. Any help?

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">

    <link rel="stylesheet" href="style.css">

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>

    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <title>Document</title>
</head>

<nav>
    <section id="navbar">
        <!-- Navigation Topper -->
        <div class="container topper-flex">
            <div class="topper-content">
                <i class="fas fa-phone"></i>
                <p class="topper-content">(354) 994-6746</p>
                <i class="fas fa-phone"></i>
                <p class="topper-content">bobbylarrys@icloud.com</p>
                <i class="fas fa-phone"></i>
                <p class="topper-content">117 Southeast 4th Ave Deerfield Beach, FL 33441</p>
            </div>
        </div>

        <!-- Mobile Navigation Header -->
        <div class="mobile-nav container">
            <img id="mobile-logo-1" src="images/maple-logo.png" alt="test" height="50" width="160"> 

            <!-- Hamburger Menu -->
            <div class="open-slide container">
                <div id="wrapper" onclick="toggleNav()">
                    <div class="main-item menu ">
                        <span class="line line01"></span>
                        <span class="line line02"></span>
                        <span class="line line03"></span>
                    </div>
                </div>
            </div>
        </div>

        <!-- Middle navigation -->
        <div id="brand">
            <div class="brand-bar container">
                <img src="images/maple-logo.png" alt="test" height="50" width="160">
                <div class="branding-bar container">
                    <div class="quote">
                        <!-- Icon -->
                        <div class="quote-block">
                            <p>NEED AN ESTIMATE</p>
                            <p>GET A FREE QUOTE</p>
                        </div>
                    </div>
                    <div class="call">
                        <!-- Icon -->
                        <div class="call-block">
                            <p>CALL US NOW</p>
                            <p>(354) 994-6746</p>
                        </div>
                    </div>
                </div>
            </div>
        </div>

        <!-- Desktop Navbar -->
        <div class="navbar-menu">
            <div class="container">
                <ul class="navbar-links">
                    <li><a class="active" href="index.html">HOME</a></li>
                    <li><a href="about.html">ABOUT</a></li>
                    <li><a href="dent.html">DENT REPAIR</a></li>
                    <li><a href="gallery.html">GALLERY</a></li>
                    <li><a href="contact.html">CONTACT US</a></li>
                </ul>
            </div>
        </div>
    </section>

</nav>

<!-- Side menu -->
<div id="side-menu" class="side-nav">
    <ul id="on-top">
        <li class="nav-item"><a class="side-active" href="index.html">HOME</a></li>
        <li class="nav-item"><a href="services.html">ABOUT</a></li>
        <li class="nav-item"><a href="jobs.html">DENT REPAIR</a></li>
        <li class="nav-item"><a href="about.html">GALLERY</a></li>
        <li class="nav-item"><a href="contact.html">CONTACT US</a></li>
    </ul>
</div>

<body>
    <script type="text/javascript" src="nav.js"></script>
    <script type="text/javascript" src="test.js"></script>
</body>
</html>
body {
    margin: 0;
    padding: 0;
}

* {
    font-family: 'Lato', sans-serif;
}

.container {
    padding: 2em 0;
}

/* hidden desktop elements */

.topper-flex,
#brand,
.navbar-menu {
    display: none;
}

/*-- -------------------------- -->
<---         NAVIGATION         -->
<--- -------------------------- -*/

.navbar {
    height: auto;
    display: flex;
    flex-direction: row;
    align-items: center;
}

/* logo and hamburger container */
.mobile-nav {
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: center;
    padding: 0;
    height: 100px;
    background: #000;
    position: relative;
}

/* Hamburger Menu */
.open-slide {
    display: inline-block;
    width: auto;
    padding: 0;
    position: absolute;
    right: 2em;
    top: 36px;
}

#wrapper {
    background: transparent;
    display:inline-block;
    margin:0px;
    position: absolute;
    cursor:pointer;
    right: 0;
}

.main-item {
    width:30px;
    height:30px;
    position:relative;
}

.line {
    position: absolute;
    height: 2px;
    width:100%;
    background:white;
    border-radius:1.5px;
    transition: all cubic-bezier(0.25, 0.1, 0.28, 1.54) 0.32s;
}

.line01 {
    top:19%;
}

.line02 {
    top:49%;
}

.line03 {
    top:79%;
}

.menu.close .line01 {
    transform:rotate(45deg);
    top:49%;
}

.menu.close .line02, .menu.close .line03 {
    transform:rotate(-45deg);
    top:49%;
}

/* Hidden Menu */
#side-menu {
    background: #231F20;
}

.side-nav {
    visibility: hidden;
    height: 0;
    transition: 0.3s 
}

.side-active {
    color: #C47625;
}

ul {
    text-align: center;
    padding: 30px 0;
    margin: 0;
}

ul a {
    text-decoration: none;
    color: #999;
    line-height: 2em;
    font-weight: 700;

    transition: 0.3s ease;
}

ul li {
    list-style: none;
}

.menu-center {
    position: absolute;
    top: 9px;
}

.menu-bottom {
    position: absolute;
    bottom: 0;
}

/* jQuery for the navigation animation */

$("#wrapper").click( function() {
    $(".menu").toggleClass("close");
});

/* Code for the toggling of the navbar */

let toggleNavStatus = false;

let toggleNav = function () {
    let getSidebar = document.querySelector(".side-nav");
    let getSidebarUL = document.querySelector(".side-nav ul");
    let getSidebarLinks = document.querySelectorAll(".side-nav a");

    if (toggleNavStatus === false) {
        getSidebarUL.style.visibility = "visible";
        getSidebarLinks.style.opacity = "1";
        getSidebar.style.height = "220px";

        toggleNavStatus = true;
    } 

    else if (toggleNavStatus === true) {
        getSidebarUL.style.visibility = "hidden";
        getSidebarLinks.style.opacity = "0";
        getSidebar.style.height = "0";

        toggleNavStatus = false;
    }
}
ryan p
  • 15
  • 5

2 Answers2

1

The line of code:

getSidebarLinks.style.opacity = "1";

was causing the issue as getSidebarLinks is an array of elements of the anchor tags.

/* jQuery for the navigation animation */

$("#wrapper").click( function() {
    $(".menu").toggleClass("close");
});

/* Code for the toggling of the navbar */

let toggleNavStatus = false;

let toggleNav = function () {
    let getSidebar = document.querySelector(".side-nav");
    let getSidebarUL = document.querySelector(".side-nav ul");
    let getSidebarLinks = document.querySelectorAll(".side-nav a");

    if (toggleNavStatus === false) {
        getSidebarUL.style.visibility = "visible";

         getSidebarLinks.forEach((item, index)=>{
          console.log(item);
          item.style.opacity = "1";
         })
        getSidebar.style.height = "220px";

        toggleNavStatus = true;
    } 

    else if (toggleNavStatus === true) {
        getSidebarUL.style.visibility = "hidden";

         getSidebarLinks.forEach((item, index)=>{
          item.style.opacity = "0";
         })
        getSidebar.style.height = "0";

        toggleNavStatus = false;
    }
}

Change the css of all the links in a foreach loop.

Helper
  • 776
  • 7
  • 17
0

Is there a specific reason that needs all these classes to be modified with js? I mean, if the menu is already hidden due to its height being 0px, the content should be already not visible. Actually, you just need a couple of lines of js to make it work.

You can take care of visibility and animation of the menu mainly with CSS rules, if well applied of course. Playing with some animation and transition you can also specify delays of appearance and other stuff. The animation will trigger when the element turns "visible".

// handle click and toggle class
$("#menu_toggler").on("click", function(e){
  e.preventDefault();
  $("#top_menu").toggleClass("open")
})
body {
  background: #20262E;
  padding: 0;
  margin: 0;
}

button {
  background: #0084ff;
  border: none;
  border-radius: 5px;
  padding: 8px 14px;
  font-size: 15px;
  color: #fff;
}
/*  */
#top_menu {
  background: white;
  height: 0;
  width: 100%;
  transition: height 2s;
  overflow: hidden;
}

#top_menu > ul > li {
  animation: FadeIn 2s linear;
  animation-fill-mode: forwards;
}

#top_menu.open {
  height: 200px;
}

#top_menu > ul > li {
  display: none;
}

#top_menu.open > ul > li{
  display: block;
  opacity: 0;
}

@keyframes FadeIn { 
  0% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}

#top_menu > ul > li:nth-child(1) {
  animation-delay: 1.25s;
}

#top_menu > ul > li:nth-child(2) {
  animation-delay: 1.50s;
}

#top_menu > ul > li:nth-child(3) {
  animation-delay: 1.75s;
}

#top_menu > ul > li:nth-child(4) {
  animation-delay: 2s;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="menu_toggler">Menu</button>
<div id="top_menu">
  <ul>
    <li>link 1</li>
    <li>link 2</li>
    <li>link 3</li>
    <li>link 4</li>
  </ul>
</div>

the transition applied to the #top_menu css rule, is gonna make your div expand in 2 seconds by its height. Will give you a smooth opening animation. Then, applying some other css rules and defining an animation will give a fadeIn effect to the links but you are free to do whatever you want with them. In this way you're not going to become crazy controlling loops and stuff.

I inserted other few css rules to extend this effect and show you how perfectly you can manage your elements without using JS

the animation-fill-mode: forwards; makes sure the elements will stay in its final state after the animation ends, with opacity: 1 indeed. The animation-delay applied to every li specifies the timing which the animation will trigger when it turns "visible".

bLuke
  • 174
  • 1
  • 8