Brandon Benefield
Brandon Benefield

Reputation: 1672

Weird mobile nav animation bug

CodePen of the nav

On the first interaction with the mobile nav, it will open and close as expected but anything after that and there's a bug. It will begin to open and close instantly or the links will appear is weird orders.

What I need is for the mobile nav to first open from right to left, have each of the links to cascade into the view, starting from About all the way to Blog, and then I would like it to reverse when leaving the view.

Right now I don't have the logic implemented for the reverse but I need to work out this bug before I get to that.

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

Upvotes: 1

Views: 51

Answers (1)

JasonB
JasonB

Reputation: 6368

There are two issues.

  • One is that you are adding a new event listener inside of the click event listener. I moved that outside.
  • The second issue is that the --open class is going to be there while the menu is opening or closing so you need another way to test open or closed status. To make the Codepen clear to understand, I just used an isOpen flag.

https://codepen.io/Jason_B/pen/jzGwQX?editors=0010

I like using classes for this, and your code shows that you do too, so you might want to have a class for open status and a class for visibility.

Upvotes: 1

Related Questions