Strangely behaving animated mobile navigation glitch

CodePen showcasing the mobile navigation

Upon initial interaction with the mobile navigation, it operates as expected. However, a bug arises with subsequent interactions. The navigation either opens and closes instantly or the links appear in a jumbled order.

My goal is for the mobile navigation to smoothly open from right to left, displaying each link in sequence, starting with About and ending with Blog. I also want the reverse animation to occur when the navigation is closed.

Currently, I have not implemented the logic for the reverse animation as I need to address this bug first.

SNIPPET

const bars = document.querySelector('.fa-bars');

bars.addEventListener('click', () => {
  const navItemsContainer = document.querySelector('.navbar__links-container');
  const navItems = document.querySelectorAll('.navbar__links-container__item');
  
  const sleep = ms => {
    return new Promise(resolve => {
      setTimeout(() => {
        return resolve();
      }, ms);
    });
  };
  
  const startNavAnimation = async () => {
    let count = 0;
    
    for (let item of navItems) {
      if (item.classList.contains('navbar__links-container__item--show')) {
        setTimeout(() => {
          item.style.transitionDelay = `${ count }s`
          item.classList.remove('navbar__links-container__item--show');
          count += .15;
        }, count);
      }
      else {
        item.style.transitionDelay = `${ count }s`
        item.classList.add('navbar__links-container__item--show');
        count += .15;
      }
    }
  };
  
  if (navItemsContainer.classList.contains('navbar__links-container--open')) {
    navItems[ navItems.length - 1 ].addEventListener('transitionend', () => {
      navItemsContainer.classList.remove('navbar__links-container--open');
    });
  }
  else {
    navItemsContainer.classList.add('navbar__links-container--open');
  }
  
  startNavAnimation();
});
body {
  margin: 0;
}

.navbar {
  background: #f2f2f2;
  display: flex;
  flex-wrap: wrap;
}

.navbar__mobile-container {
  display: flex;
  justify-content: space-around;
  width: 100%;
}

.fa-bars {
  cursor: pointer;
}

.navbar__links-container {
  background: inherit;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  list-style: none;
  margin: 0;
  overflow: hidden;
  padding: 0;
  position: absolute;
  top: 20px;
  left: 100%;
  transition: left .25s, width .25s;
  width: 0%;
}

.navbar__links-container__item {
  left: 52px;
  margin-bottom: 1rem;
  position: relative;
  transition: left .25s;
  width: auto;
}

.navbar__links-container--open {
  left: 0;
  width: 100%;
}

.navbar__links-container__item--show {
  left: -63px;
}
    <nav class="navbar">
      <div class="navbar__mobile-container">
        <div class="navbar__logo-container">
          <a class="navbar__logo-container__logo">BB</a>
        </div>
        
        <div class="navbar__hamburger-container">
          <i class="fas fa-bars">MENU</i>
        </div>
      </div>

      <ul class="navbar__links-container">
        <li class="navbar__links-container__item">
          <a class="navbar__links-container__item__link">About</a>
        </li>
        <li class="navbar__links-container__item">
          <a class="navbar__links-container__item__link">Portfolio</a>
        </li>
        <li class="navbar__links-container__item">
          <a class="navbar__links-container__item__link">Blog</a>
        </li>
      </ul>
</nav>

NOTES

  • My suspicion is that the issue lies within the first if statement in the bars event-handler. It seems to be waiting for the transitionend event without calling startNavAnimation first.

Answer №1

There are a couple of things to consider.

  • Firstly, it is important to note that adding a new event listener within the click event listener can lead to issues. I have resolved this by moving it outside.
  • Additionally, the presence of the --open class both during menu opening and closing phases requires an alternative method to determine the status of open or closed. To enhance clarity in the Codepen example, I have introduced an isOpen flag.

Visit this link for reference.

I personally prefer using classes in these scenarios, and it seems like you do too. Consider having a separate class for open status and another for visibility in your code.

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

The placeholder feature seems to be malfunctioning when it comes to entering phone numbers in a react

I am working on a MUI phone number form field. I want the placeholder to show up initially, but disappear when the user starts typing. How can I achieve this functionality in my code? import React from "react"; import MuiPhoneNumber from " ...

Enhance user experience by implementing an interactive feature that displays

I have a form for adding recipes, where there is an ingredients button. Each recipe can have multiple ingredients. When the button is clicked, an input field for adding ingredients should appear below the ingredient button. What I've attempted so far ...

Unveiling the Mystery: Why YUI-3 Grids & Google Chrome Cause Overlapping Texts

Although I'm not well-versed in UI design, I find myself having to work on some CSS for a side project. Currently, I am utilizing YUI-3 files such as grids, reset, and fonts, all version 3.9.1. The main issue I am encountering is that the text inside ...

Determining the repetition and placement of background images when employing multiple backgrounds

Is it possible to apply two background images to the same div? I want one image to repeat along the x-axis and the other to appear only once. I've tried using multiple background images, but I'm not sure how to target specific rules for each bac ...

Having trouble with uploading an image in Laravel using a modal?

For my laravel inventory system, I am facing an issue with uploading images for products. The old code I used for image upload is not working in my current project where I am utilizing a modal and ajax request to save inputs in the database. Can anyone pro ...

What is the best way to access a variable from a .js file?

Is there a way to access a variable defined in a JavaScript file from a Vue file and pass it to the Vue file? In the following code snippet, there is a template.js file and a contact.vue file. The template file converts MJML to HTML and saves the output to ...

Creating a personalized design for Bootstrap Badge

Looking to customize the shape of bootstrap badges from the default ellipse to a rectangle with rounded corners. Any tips on the best approach to accomplish this? ...

Is there a way to improve efficiency in JavaScript and JSON by reducing the size of the array?

My partner and I are currently collaborating on the development of a small web application. This app serves as an information hub, sourcing data from a JSON file that is expected to contain around 150 items, each with approximately 130 properties. As we c ...

What are the steps for implementing if-else statements in JavaScript when working with multiple dropdown lists?

I have encountered an issue while trying to display options in multiple drop-down lists. Only two words (CHENNAI AND IOS-XE, BANGALORE AND IOS-XR) are being displayed and the rest of the words are not appearing. Can someone provide assistance on fixing thi ...

Why won't the div move when I click it?

Could you please explain why my JavaScript code isn't functioning as expected? The intended behavior is for the 'mark' div to move to the current mouse coordinates upon clicking within the map. ...

A fragmented rendering of a gallery featuring a CSS dropdown menu

Hey there! I'm a newbie coder seeking some assistance. Recently, I stumbled upon a tutorial online that taught me how to create a drop-down menu. However, whenever I hover over "Gallery" on my website, things go haywire and the layout gets all messed ...

Utilizing a server for seamless communication between a mobile device and a website

Exploring a simple setup idea here: Imagine having a mobile app with a page that contains 4 lines of content (utilizing phonegap for development). The plan is to have a web page where data for those 4 lines can be inputted. Once the information is submitt ...

implement css property solely when device is in landscape orientation

I am facing an issue with applying CSS to a mobile device, specifically for horizontal orientation. When the device is in a vertical position, the page appears blank, and different CSS loads for desktop view. Although I have managed to make the desktop CS ...

What is the best way to use Immer to update Zustand state when incorporating objects that are added through a controlled form using React-Hook-

Having some trouble with integrating Zustand and Immer using React-Hook-Form. My goal is to capture a series of values from a form, store them in a list, and allow for the addition of new objects to that list. In this scenario, the user inputs data for a ...

What are the steps to establish a Z-axis coordinate system in three.js?

When working with three.js, the Y axis typically represents up and down, while the Z axis represents forward and backward. However, I want to switch this so that the Z axis represents up and down, and the Y axis represents forward and backward. Here is an ...

How can I invoke a function within a directive-generated HTML element's scope?

I created a custom directive that utilizes element.html() to set the HTML content. Within this HTML code, I would like to be able to invoke functions from the scope where the directive is being used. Here's an example: app.directive('myDirective ...

Creating a Responsive Bootstrap Webpage

I attempted to replicate a sign-in page using Bootstrap from this link: Prior to this, I had already created a page without using Bootstrap code. <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Mainpage.aspx.cs" Inherits="project.Mainpage" ...

Whenever I include an onClick event to a div element, the entire webpage fails to display

Currently taking on the task of developing a seat booking website. I am encountering an issue with adding an event listener to a particular div element, which should trigger a function to store the value of the div. However, upon implementing the onClick e ...

Despite creating a new array, Vuetify 2 continues to display 10 in the pagination options

I am facing an issue in Vuetify 2 where I have set the pagination options of a data table to be [50,60,70], but on the page, it displays [10,50,60,70]. It seems to be combining the default 10 into the list. https://codepen.io/anon/pen/NQRRzY?&editable ...

Guide on transforming a select dropdown into a ul dropdown

I am attempting to transform my select dropdown menu into an unordered list (ul) in order to create a bootstrap button that will display the ul, allowing the list items to function as options. <select id="sortField" onchange="refreshPage('{$pageBa ...