Can I make this admin navigation simpler or better?

I have a vision to create a navigation for an admin template that works on both mobile and desktop. So far I have done a test. But I think my code is a bit clumsy, so I wonder if there is a simpler way to write this code. The meny should work with both the hamburger meny AND when resizing the window. Both phone and desktop. The menu should expand and collapse in two steps.

My question is if there is a way to simplify this further? Or make the navigation better / simpler?

http://94.237.92.101:6060/home

/* manage the sidenav via resizing and hamburger */
window.addEventListener("load", close);
 
function close() {
  var win = window.innerWidth;
  if (win < 769) {
    if (localStorage.menu == "opensub") {
      subnav.classList.add("close")
      window.localStorage.setItem('menu', "closesub");
    } else {
      subnav.classList.remove("close")
      window.localStorage.setItem('menu', "opensub");

    }
  }
}

window.addEventListener("resize", resize);

function resize() {
var win = window.innerWidth;
  if (win < 480) {
    window.localStorage.setItem('menu', "closemain");
  } else if (win < 769) {
    window.localStorage.setItem('menu', "openmain");
  } else {
    window.localStorage.setItem('menu', "opensub");
  }
  menu() // update menu
}

function menu() {
  switch (localStorage.menu) {
    case "openmain":
      mainnav.classList.remove("close")
      subnav.classList.add("close")
      window.localStorage.setItem('menu', "opensub");
      break;
    case "opensub":
      mainnav.classList.remove("close")
      subnav.classList.remove("close")
      window.localStorage.setItem('menu', "closesub");
      break;
    case "closesub":
      mainnav.classList.remove("close")
      subnav.classList.add("close")
      window.localStorage.setItem('menu', "closemain");
      break;
    case "closemain":
      mainnav.classList.add("close")
      subnav.classList.add("close")
      window.localStorage.setItem('menu', "openmain");
      break;
  }
}

I can’t really comment on the JS but it could be simplified by applying one class to the nav element instead of a class on the mainnav and then a class on the subnav. Both mainnav and subnav are children of nav so you can control both by just changing the class on the nav.

It would also be better to use matchmedia rather than the resize event which if not throttled will cause bottlenecks and make the page appear slow.

I’ll leave it to the JS gurus to comment on the code explicitly :slight_smile:

(Design looks pretty clean by the way :))

1 Like

Dammit - I’m seeing nothing in the JS that I wouldn’t do. There might be something after the matchmedia is in place though :wink:

2 Likes

I have now implemented matchmedia using this code. Can this be done simpler? Preferable with less lines of code.

http://94.237.92.101:6060/

const w480 = window.matchMedia('screen and (max-width: 480px)');

w480.addEventListener('change', event => {
  if (event.matches) {
    window.localStorage.setItem('menu', "closemain");
    menu() // update menu
  } 
})

const w768 = window.matchMedia('screen and (min-width:481px) and (max-width: 769px)');

w768.addEventListener('change', event => {
  if (event.matches) {
    window.localStorage.setItem('menu', "openmain");
    menu() // update menu
  } 
})

const w769 = window.matchMedia('screen and (min-width: 770px)');

w769.addEventListener('change', event => {
  if (event.matches) {
    window.localStorage.setItem('menu', "opensub");
    menu() // update menu
  } 
})

@Paul_Wilkins will probably having something to say but I have a codepen where the media queries are kept in an array and although the code isn’t much smaller it seems easier to manage (for me that is).

1 Like

I tried with this approach. But it was more unpredictable because it interfered with other code. As I understood it.

It seems to work fine in the demo but if you have yours working ok then probably best to stick with it :wink:

1 Like

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.