Javascript toggle navigation with sliding and fading effects

Tap on the flower to reveal the menu. I have successfully implemented the animation for "process" fading in after the menu opens. However, I am struggling to reverse the animation when collapsing the menu. I want "process" to fade out before the menu closes again. Can anyone provide assistance with this?

function toggleClass() {
    var spin = document.getElementById("nav");

    spin.classList.toggle('in');
    spin.classList.toggle('out');
}

const delay = ms => new Promise(res => setTimeout(res, ms));
const fadeInAnimation = async () => {

    var element1 = document.getElementById("text1");
    var element2 = document.getElementById("text2");
    var element3 = document.getElementById("text3");

    await delay(300);

    element1.classList.toggle("show");
    element2.classList.toggle("show");
    element3.classList.toggle("show");
}

document.querySelector('#nav').addEventListener('click', fadeInAnimation);
:root{
  --seconds: 5s;
  --fast: 2s;
}

nav{
  position: fixed;
  display: flex;
  justify-content: space-between;
  align-items: center;
  z-index: 10px;
  padding-top: 20px;
  width: 100%;
}

nav img{
  width: 50px;
}

/* INN OUT */

#nav{
    height: auto;
    display: flex;
    align-items: center;
    justify-content: flex-start;
    border-radius: 50px;
    padding: 10px;
    background-color: white;
    margin-right: 20px;

    /*drop shadow*/
    -webkit-box-shadow: 0px 10px 30px 0px rgba(0,0,0,0.10);
    -moz-box-shadow: 0px 10px 30px 0px rgba(0,0,0,0.10);
    box-shadow: 0px 10px 30px 0px rgba(0,0,0,0.10);

}
.in {
    width: 50px;
}

.out {
    width: 400px;

}
.transition{
  -webkit-transition: all 0.2s ease-in-out;
  -moz-transition:all 0.2s ease-in-out;
  -o-transition:all 0.2s ease-in-out;
  transition::all 0.2s ease-in-out;
}


#navtext{
  width: 100%;
  display: flex;
  flex-direction: row;
  justify-content: space-around;
}
.style{
  display: flex;
  background-color: white;
  justify-content: center;
  align-items: center;
  padding: 10px 15px 10px 15px;
  border-radius: 40px;
  color: lightgrey;
  transition: 0.1s;

}
#text{
  display: none;
}
.noshow{
  display: none;
}
.show{
  display: flex;
}

.show:hover{
  color: black;
  background-color: lightgrey
}
<nav>
  <div id="nav" class="in transition">
    <img id="spin" src="https://i.dlpng.com/static/png/762080_preview_preview.png" class="rotating spin" onclick="toggleClass()">
    <div id="navtext">
        <a id="text1" class="noshow style">Process</a>
        <a id="text2" class="noshow style">Process</a>
        <a id="text3" class="noshow style">Process</a>
    </div>
  </div>
</nav>

Answer №1

I have made adjustments to the JavaScript code for toggling the items, while maintaining the in/out toggle functionality.

Subsequently, based on the classes 'in' and 'out', I will handle the visibility of items using CSS:

.transition.in .noshow{
  visibility: hidden;
  opacity: 0;
  height:0;
}
.transition.out .noshow{
  visibility: visible;
  opacity: 1;
  height:auto;
  transition: 0.7s;
}

The decision to not utilize display: none || flex was intentional in order to preserve the transition effect.

Below is the revised code snippet:

function toggleClass() {
    var element = document.getElementById("nav");

    element.classList.toggle('in');
    element.classList.toggle('out');
}

document.querySelector('#nav').addEventListener('click', null);
:root{
  --seconds: 5s;
  --fast: 2s;
}

nav{
  position: fixed;
  display: flex;
  justify-content: space-between;
  align-items: center;
  z-index: 10px;
  padding-top: 20px;
  width: 100%;
}

nav img{
  width: 50px;
}

/* INN OUT */

#nav{
    height: auto;
    display: flex;
    align-items: center;
    justify-content: flex-start;
    border-radius: 50px;
    padding: 10px;
    background-color: white;
    margin-right: 20px;

    /*drop shadow*/
    -webkit-box-shadow: 0px 10px 30px 0px rgba(0,0,0,0.10);
    -moz-box-shadow: 0px 10px 30px 0px rgba(0,0,0,0.10);
    box-shadow: 0px 10px 30px 0px rgba(0,0,0,0.10);

}
.in {
    width: 50px;
}

.out {
    width: 400px;

}
.transition{
  -webkit-transition: all 0.2s ease-in-out;
    -moz-transition:all 0.2s ease-in-out
    -o-transition:all 0.2s ease-in-out;
    transition::all 0.2s ease-in-out;
}


#navtext{
  width: 100%;
  display: flex;
  flex-direction: row;
  justify-content: space-around;
}
.style{
  display: flex;
  background-color: white;
  justify-content: center;
  align-items: center;
  padding: 10px 15px 10px 15px;
  border-radius: 40px;
  color: lightgrey;
  transition: 0.1s;

}
#text{
  display: none;
}
.transition.in .noshow{
  visibility: hidden;
  opacity: 0;
  height:0;
}
.transition.out .noshow{
  visibility: visible;
  opacity: 1;
  height:auto;
  transition: 0.7s;
}

.noshow:hover{
  color: black;
  background-color: lightgrey
}
<nav>
  <div id="nav" class="in transition">
    <img id="spinn" src="https://i.dlpng.com/static/png/762080_preview_preview.png" class="rotating spinn" onclick="toggleClass()">
    <div id="navtext">
        <a id="text1" class="noshow style">Process</a>
        <a id="text2" class="noshow style">Process</a>
        <a id="text3" class="noshow style">Process</a>
    </div>
  </div>
</nav>

Answer №2

Ensure that only one "is-active" class is applied to the #nav element, utilize JavaScript to toggle it and style its descendants using CSS.

Implement the transition-delay property in CSS to intelligently adjust the timing of the transition when toggling:

const nav = document.querySelector("#nav");
nav.addEventListener("click", () => nav.classList.toggle("is-active"));
nav {
  position: fixed;
  top: 10px;
  left: 10px;
  z-index: 100;
}

#navImg {
  width: 50px;
  cursor: pointer;
  display: inline-block;
  transition: transform 0.6s ease-in-out;
}

#nav {
  display: flex;
  padding: 10px;
  border-radius: 50px;
  background-color: white;
  box-shadow: 0px 10px 30px 0px rgba(0, 0, 0, 0.10);
}

#navText {
  display: flex;
  flex-flow: row nowrap;
  width: 0;
  transition: 0.3s ease-in-out 0.3s;
  overflow: hidden;
}

#navText a {
  display: inline-flex;
  align-self: center;
  padding: 10px 15px 10px 15px;
  margin-left: 10px;
  border-radius: 40px;
  color: #aaa;
  text-decoration: none;
  opacity: 0;
  transition: opacity 0.3s ease-in-out 0s;
}

/* ACTIVATE MODE */
#nav.is-active #navText {
  transition-delay: 0s; /* reverse delay timing logic */
  width: 270px; /* for demonstration purposes only, can be calculated dynamically with JS */
}
#nav.is-active #navText a {
  transition-delay: 0.3s; /* reverse delay timing logic */
  opacity: 1;
}
#nav.is-active #navImg {
  transform: rotate(1turn);
}
<nav>
  <div id="nav">
    <img id="navImg" src="https://i.dlpng.com/static/png/762080_preview_preview.png">
    <div id="navText">
      <a href="#!">Process</a>
      <a href="#!">Process</a>
      <a href="#!">Process</a>
    </div>
  </div>
</nav>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Looking to add a dynamic drop-down menu to my search bar, similar to Google search

Is there a way to create a dynamic drop-down list where, when a user enters the first letter of a country name, the list displays countries with names starting with that letter? It's similar to the functionality of a Google search bar. The country nam ...

HTML & jQuery guide: The correct way to execute a function on an anchor element (compatible across all browsers)

My webpage contains several anchor tags that are used to trigger a function. Although everything is functioning correctly, I am unsure of the best way to ensure cross-browser compatibility, as different methods can be found online. I have opted to use jQu ...

Are you in need of a JavaScript data validation tool?

Trying to find a library that can validate input in a specific format, such as: { points: array of { x: positive and less than 20, y: positive and less than 15 } } Ideally, it should work on both server and client sides and either return a boolean or th ...

The regular expression used for validating domains does not function properly in the Safari browser

I am struggling with a JavaScript regular expression error that Safari is giving me. I am trying to validate a domain, but for some reason, this specific part (?<!-) is causing the issue because the domain name should not end with a hyphen. ^((?!-)[A-Z ...

There seems to be a connection issue between my Jquery and HTML, as they

I've hit a roadblock because my jQuery isn't connecting and I can't seem to figure out why. It's been stumping me for hours. Here is the HTML code snippet from exercise6.html: <!DOCTYPE html> <html lang="en> <h ...

Error Not Captured: [$rootScope:infdig]

Here is a code snippet that I wrote: <tbody ng-repeat="dtataOne in dataOnes()"> <tr> <td>My Data</td> <td class="task-container ui-sortable" colspan="6" ng-model="dtataOne.MyModel" ui-sortable="sortableOption ...

"Div does not perfectly match the height of its parent div when using the 'inherit' value

I have 3 divs inside a parent div, intended to be arranged like so: ______________________________________ | | | HEADER | |______________________________________| ____ ________________ ...

How about a unique scrolling experience?

Currently, I am attempting to prevent the scroll position from being locked after a single scroll for one second while scrolling down one section at a time. However, I am encountering unexpected behavior. const [nextSection, setNextSection] = useState(&ap ...

Ways to locate the div that specifically contains a word with an exact match

I recently came across this link: jQuery :contains(), but to match an exact string After finding the div I need, I want to modify its attributes using the filter option. It should look something like this: $('#viewer .textLayer div:contains(' ...

Custom cellRenderer prevents Ag Grid's autoHeight and wrapText features from functioning properly

I've been attempting to adjust the formatting of a long cell value by wrapping the text. According to the documentation, setting autoHeight=true and wrapText=true works fine without any cellRenderer components. However, when using a cellRendererFramew ...

Which framework should be used: client-side or server-side?

I am working on a project similar to craiglist, where users can post announcements for everyday items like cars and flats. I have already developed a significant portion of the backend using a RESTful API in three-tier architecture with Java, connecting to ...

Tips on retrieving an array in a different page post ajax transfer

I have an array named student. I am in need of passing this array to another PHP page using the POST method instead of GET, due to its potentially large size. Currently, I am attempting to open a new page called sheet.php and display the contents of the s ...

Error Message: discord.js is unable to retrieve the specified property 'find' due to it being undefined, resulting in

While working on a command for my discord bot, I encountered an error. As I am new to programming, please forgive me if it's something simple that I couldn't figure out. TypeError: Cannot read property 'find' of undefined at Object. ...

The main-panel div's width increase is causing the pages to extend beyond the window's width limit

I recently downloaded a Reactbootstrap theme and managed to integrate it with NextJS successfully. However, I am facing an issue where my <div className="main-panel"> in the Layout.js is extending slightly beyond the window. It seems like t ...

Update the value after verifying the element

I am trying to retrieve data from my database and update the values when an element is clicked (accepting user posts). The code I have written seems to work, but I encounter an error stating that props.actions is not a function when clicking on an element. ...

How can you modify the styling of a single child element within a grandparent container and then revert it back to its original state

My goal is for #homeContainer to occupy the entire width of the page, but a higher-level element is restricting its width and margin. Below you can see the DOM structure. By removing margin: 0 auto, I am able to achieve full width. How can I specifically ...

Is it possible to resize an inline SVG element without modifying the <svg> tag?

Utilizing a Ruby gem known as rqrcode, I am able to create a QR code in SVG format and send it as an API response. Within my frontend (Vue.js), I am faced with the task of displaying the SVG at a specific size. Currently, my code appears as follows, rende ...

Tips for aligning 'textarea' and 'a' (button) tags in a single row

<div class="row"> <a class="btn btn btn-success btn-block"><i class="fa fa-thumbs-up"></i>Ok</a> </div> <div class="row"> <textarea name="textareaAxs" ></textarea> <a class="btn btn btn- ...

Tips for transferring data and executing a PHP script without page refresh

In my quest to access a product API from a web interface seamlessly, without causing any disruption to the user experience, I have encountered some challenges. The webpage and the main machine operate on separate servers, forcing me to resort to using PHP ...

access the useState value within the event listener

I need to show a list of coordinates collected from a click event on a DIV. The listener should only activate when a button is clicked. import { createRoot } from "react-dom/client"; import React, {useCallback, useEffect, useState} from 'rea ...