简体   繁体   中英

My Side navbar doesn't collapse after page reload

I have a side navbar using HTML, SCSS and js. When I click reload, it goes to uncollapse state.

HTML

<nav class="nav" id="myNav">
    <button class="nav__toggle" id="toggle-btn">
        <span class="hamburger"></span>
    </button>
    <ul>
        <li class="brand">
            <a href="">
                <img src="/images/logo.png" class="img-fluid" alt="NC Designs logo">
            </a>
        </li>
        <li><a href="#creative">My creatives</a></li>
        <li><a href="#about">About me</a></li>
        <li><a href="#portfolio">My Portfolio</a></li>
        <li><a href="#clients">Clients</a></li>
        <li><a href="#testimonials">Testimonials</a></li>
        <li><a href="#contact">Contact me</a></li>
    </ul>
</nav>

SCSS

.nav {
  position: absolute;
  text-align: center;
  right: 0;
  width: 260px;
  height: 100vh;
  background: var(--clr-light);
  box-shadow: 0 0 3em #00000026;
  transform: translateX(100%);
  transition: transform 300ms cubic-bezier(0.5, 0, 0.5, 1);

  ul {
    list-style: none;
    margin: 0;
    padding: 0;
    .li:nth-child(0){
      margin-bottom: 1rem!important;
    }

    li {
      margin-bottom: 2em;
      display: flex;
      
      a {
        text-decoration: none;
        color: var(--clr-dark);
        padding: .5em;
        flex: 1;
        &:hover {
          text-decoration: underline;
          color: var(--clr-primary);
        }
      }
    }
  }
}
.brand{
  margin-top: 2em;
}
.brand img{
  height:100px
}
.nav__toggle {
  position: absolute;
  top: 2em;
  left: 0;
  transform: translateX(-100%);
  background: var(--clr-light);
  padding: 1em 0.5em;
  border: 0;
  border-radius: 0.25em 0 0 0.25em;
  cursor: pointer;
  transition: left 600ms ease-in-out, padding 500ms,
    transform 3500ms ease-in-out, opacity 200ms linear;
  &:focus {
    outline: 0;
    box-shadow: 0 0 0 1px rgba(238, 99, 82, 0.5);
  }
}

.hamburger {
  display: block;
  position: relative;
  &::before,
  &::after {
    content: "";
    position: absolute;
    left: 0;
  }
  &::before {
    bottom: 6px;
  }
  &::after {
    top: 6px;
  }
}

.hamburger,
.hamburger::before,
.hamburger::after {
  width: 2em;
  height: 3px;
  background: var(--clr-dark);
  transition: transform 350ms ease-in-out, opacity 200ms linear;
}

/* Navigation open styles */
.nav-open {
  .nav {
    -webkit-transform: translateX(0);
    transform: translateX(0);
  }
  /* Change this stuff below */
  .hamburger {
    -webkit-transform: rotate(45deg) scale(0.7);
    transform: rotate(45deg) scale(0.7);
    &::before {
      opacity: 0;
    }
    &::after {
      transform: rotate(90deg) translate(-6px) scale(1);
    }
  }
  .nav__toggle {
    position: absolute;
    top: 2em;
    left: 98%;
    transform: translateX(-100%);
    background: var(--clr-light);
    padding: 1em 0.1em;
    border: 0;
    border-radius: 50%;
    box-shadow: 0 0 0.5em rgba(0, 0, 0, 0.2);
    margin-bottom: 50px;
    &:focus {
      outline: 0;
      border-radius: 50%;
      box-shadow: 0 0 0 1px rgba(238, 99, 82, 0.25), 0 0 0.5em rgba(0, 0, 0, 0.25);
    }
    &:hover {
      outline: 0;
      border-radius: 50%;
      box-shadow: 0 0 0.5em rgba(0, 0, 0, 0.55);
    }
  }
}

JS

<script>
    const navToggle = document.querySelector('.nav__toggle');
    const navFocus = document.querySelector('nav ul li a');

    navToggle.addEventListener('click', () => {
        document.body.classList.toggle('nav-open');
    });

    /* 
       Allow the toggle to work if the tab key is used to access menu...
       I'm not sure if this is the best way or if it works all the time.
       I tried experimenting with keyup and the keycode but this seemed simple.
    */
    navFocus.addEventListener('focus', () => {
        document.body.classList.toggle('nav-open');
    });
</script>

repo link

Note: when I click the refresh second time, the navbar opens (uncollapsed), that should not happen (should remain collapsed even if I reload from the uncollapsed state (open navbar state). What should I do?

This behavior is expected if you were to reload the page. However, if you wanted to override this, you need a way to save the state between page refreshes. I think you should take a look at the sessionStorage API: https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage

A couple of things to point you in the right direction: When you load the page, you should access the state of the sidebar. I think opened or closed would be enough to remember the state of the sidebar. Something like:

const navBarKey = "navBarState"; // using variable to prevent typos
const navBarState = sessionStorage.getItem(navBarKey);
const open = "open"; // using variable to prevent typos
const navOpen = 'nav-open'; // using variable to prevent css class typos

if(navBarState === open){
 // this code will run when first started. If not, you may need to add some window.onload logic. 
 // if the saved state is open, add 'nav-open'
 body.classList.add(navOpen);
}

const navToggle = document.querySelector('.nav__toggle');
navToggle.addEventListener('click', () => {
 
 if(body.classList.contains(navOpen)) {
   // if already open, remove 'nav-open' and remove 'navBarState' from sessionStorage
   body.classList.remove(navOpen);
   sessionStorage.removeItem(navBarKey)
 } else {
   // if not open, add 'mav-open' and add 'navBarState' to sessionStorage
   body.classList.add(navOpen);
   sessionStorage.setItem(navBarKey, open)

 }
});        

sessionStorage will persist only while the window/tab is open, and will clear if you exit the browser. localStorage , however, will persist even after the brower is closed. So, if you wanted to persist after restarting the browser, you should instead use localStorage. https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage

I hope this is enough for you to get started! There are of course, different ways to handle this/refactoring opportunities, but for the given code you have at hand, this should suffice.

The problem was with absolute positioning.

nav loses its absolute position after reload. After changing nav's position to fixed, it worked. No Javascript changed were required.

.nav {
  position: fixed;
}

Thank you!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM