Navigation menu js experiment help

Hi everyone,
I’m struggling to understand how to approach this js goal. My goal is to target the #nav-list until the screen reaches 1000px. When the user clicks on the anchor items by class ‘nav-link’, the nav-list will disappear for 500 milliseconds before being switched on again. Thereby when the user clicks the bar they can see the nav menu as if nothing happened.

Very much not sure how to approach. Any help and advice would be greatly appreciated.

My project

https://codepen.io/Laurie312/pen/YzxJJbx

I’m afraid I don’t understand what you want to do here.

You want to do something special with the nav menu when the width of the view port is less than 1000px wide?

You want the nav menu to disappear for half a second when a linked in the nav menu is clicked on? I’m not sure I understand the purpose of this?

I don’t understand what you mean by this? What is “the bar”? Are you referring to the hamburger menu icon?

I’ll take a guess at what you are trying to do. Let me know how close I get. When the view port is narrow enough to show the hamburger menu icon and the user clicks the icon to display the nav menu, you want the menu to be hidden again after the user clicks on a link in the menu.

1 Like

I don’t understand what you are trying to do either but I will comment on the code.

  1. listItems is a “collection” of elements, you have to loop it and attach the listener to each of the items.

  2. setInterval takes a callback and an interval. Also, I’m guessing what you really want is setTimeout (same signature but takes a delay).

  3. You are toggling an inactive class but you have no such class in the CSS.


This code doesn’t really do anything but is just to give an example of what I mean. I’m using querySelectorAll instead of getElementsByClassName.

const listItems = document.querySelectorAll(".nav-link");

listItems.forEach((listItem) => {
  listItem.addEventListener("click", () => {
    navList.classList.add("inactive");
    setTimeout(() => {
      navList.classList.remove("inactive");
    }, 500);
  });
});
1 Like

Sorry for the confusing explanation.

Yes!

In a previous project. I figured out how to get a list to disappear, but on clicking the bars the list didn’t reappear straight away instead you had to click the bars two times to re activate the list

Previous project

https://codepen.io/Laurie312/pen/QWMOZdO

I guess I’m looking for a way where instead of having to click on the bars to un hide the list, the list un hides automatically…

Maybe this still doesn’t make sense, if thats the case could you check the project link above and click the mobile links to understand where I’m coming from…

OK I think I follow most of your comment.

I have added .nav-list.inactive to css.

Would a for loop work here?

When the screen is under 1000px there is a bar that opens up the <ul> which holds the anchor tags. When a user clicks the anchor tag I would like the <ul> list pop up to go away! As long as the user doesn’t have to click the bar two times to reactivate the <ul> I don’t mind whether it’s setInterval, setTimeout etc. My hypothetical method may be completely superfluous so I’m 100% open to your suggestions on this!

If it can be a simple on/off boolean then I will be a very happy man

You really shouldn’t need to use any sort of timing mechanism to do this unless you want to add a delay to the menu disappearing for some reason. @lasjorg’s suggestion to use a click handler on the links in the menu is spot on. You “could” use it to toggle a class that controls the visibility of the menu. But if you want to be accessible (which you should) then you should do the following things:

  • Change the hamburger icon from a link to a button (links go places, buttons do things, such as controlling the visibility of a menu).
  • Add the aria-expanded attribute to the button. Initially it will be set to aria-expanded="false" since the menu is hidden by default. Use JS to toggle the value between true and false as the user opens/closes the menu.
  • The click handler on the links will set aria-expanded="false" since you always want to close the menu when you click a link.
  • The CSS can use the [aria-expanded] attribute to control visibility. This attribute is the boolean you are looking for to control the visibility of the menu.
  • Also, you need to add a text label to the hamburger button so that screen readers know how to announce it. You can either add text inside the button itself and visually hide it (google it) or you could use the aria-label attribute to give the button an accessible name (e.g. aria-label="Menu").
1 Like

Yes, but I don’t suggest using one. forEach is much cleaner to read and reason about.

If you just need to hide the menu the code I posted would work if you just replace the class with the active class. But I’m still not sure if that is all you are trying to do.

Summary
const toggleButton = document.getElementById('toggle-button');
const navList = document.getElementsByClassName('nav-list')[0];
const listItems = document.querySelectorAll(".nav-link");

toggleButton.addEventListener('click', (evt) => {
    evt.preventDefault();
    navList.classList.toggle('active')
})

listItems.forEach((listItem) => {
  listItem.addEventListener("click", () => {
    navList.classList.add("active");
    setTimeout(() => {
      navList.classList.remove("active");
    }, 500);
  });
});
1 Like

@lasjorg and @bbsmooth

Well I certainly can’t accuse either of you two of talking down to me. :rofl:

I’ll go and bang my head against a wall for a couple of days and let you know how I get on…

This is a small example project on responsive navbar, the way i understand you want it to be.
For the 500ms delay effect, id try to solve it with CSS first(transition), before going for JS setTimeout solution

1 Like

@Sylvant

This is excellent advice. I’ve been following Smilgas videos quite a bit recently. There’s something quite endearing about him… He’s a good teacher and he talks about how to solve design issues with just inspector and css in the videos on nav and sidebars that I watched.

Anyway, thanks again for your great advice!

1 Like