Add active class to current element

How to add the active class to current element with this responsive navigation bar: https://www.w3schools.com/howto/howto_js_topnav_responsive.asp

When the menu buttons are clicked the 'active' class doesn't change.

Any advice most welcome.
Jeremy JohnsonAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

leakim971PluritechnicianCommented:
Test page : http://jsfiddle.net/dk5y7jz1/
window.onload = function() {
	var links = document.getElementById("myTopnav").getElementsByTagName("a");
  for(var i=0;i<links.length;i++) {
  	links[i].onclick = function() {
      document.getElementsByClassName("active")[0].className = "";
    	this.className = "active";
    }
  }
}

Open in new window

0
Jeremy JohnsonAuthor Commented:
Thanks but this breaks the hamburger menu icon from appearing on smaller screens.

I should mention I have also used sub-menu drop down items e.g. https://www.w3schools.com/howto/howto_css_dropdown_navbar.asp
0
leakim971PluritechnicianCommented:
hamburger menu icon?
I've no idea of what you're talking about...
your question was : "When the menu buttons are clicked the 'active' class doesn't change."
I believe it's now answered...
0
Big Business Goals? Which KPIs Will Help You

The most successful MSPs rely on metrics – known as key performance indicators (KPIs) – for making informed decisions that help their businesses thrive, rather than just survive. This eBook provides an overview of the most important KPIs used by top MSPs.

Jeremy JohnsonAuthor Commented:
If you resize the window smaller from the Try it Yourself link in the tutorial you will see the three line menu icon in the top right. I believe this is called a 'hamburger' menu.

https://www.w3schools.com/howto/tryit.asp?filename=tryhow_js_topnav

Thanks for your help.
0
Julian HansenCommented:
Try this code
window.addEventListener('load', function() {
  document.getElementById('myTopnav').querySelectorAll('a').forEach(function(aItem) {
    aItem.addEventListener('click', function(e) {
      e.preventDefault();
      document.querySelectorAll('.active').forEach(function(remItem) {
        remItem.classList.remove('active');
      });
      aItem.classList.add('active')
    });
  })
});

Open in new window

Working sample here
0
Jeremy JohnsonAuthor Commented:
Thanks! That is changing the active class but breaks the menu links for the dropdowns.

Here is a jsfiddle for what I have (although for some reason the hamburger menu doesn't expand in the jsfiddle but does on my working version):

https://jsfiddle.net/jns_johnson/Lzqen8bo/

Sorry if I missed something.
0
Julian HansenCommented:
Thanks! That is changing the active class but breaks the menu links for the dropdowns.
What drop downs? There were no dropdowns in the original question - did we move the goal posts?

I don't see the code I proposed in your fiddle either - so not sure how it was supposed to work.

Be that as it may - here is an updated code snippet and sample demonstrating its use
window.addEventListener('load', function() {
  document.getElementById('myTopnav').querySelectorAll('a, .ddropdown').forEach(function(aItem) {
    aItem.addEventListener('click', function(e) {
	  e.preventDefault();
      document.querySelectorAll('.active').forEach(function(remItem) {
        remItem.classList.remove('active');
      });
      aItem.classList.add('active');
    });
  })
});

Open in new window

Updated code sample here

Note: Because my sample boiler plate uses Bootstrap which changes the .dropdown style I have renamed the dropdown style in your code to ddropdown.
0
Jeremy JohnsonAuthor Commented:
Thanks Julian, sorry I mentioned the dropdowns in my first comment after asking the original question but probably should have edited the question.

This is almost working but the menu links still don't seem to change the page, for me, but I can see the links display in the bottom right on hover.

I didn't leave your javascript on the jsfiddle as I wanted to provide a working version, but I've added it here now:
https://jsfiddle.net/jns_johnson/Lzqen8bo/10/

What could be stopping the links changing the page?
0
Julian HansenCommented:
Let's take a step back.

You can't set the class AND change the page. When you "change" the page you refresh the page and lose whatever changes you made.

The pages are not "changing" because of line 4
e.preventDefault();

Open in new window

You need to take that out. I put it in because you appeared to want a solution that did not require going back to the server (setting the class)

What you need to do is in your server code - when you render the page out - check to see what menu item triggered the request and add the class into the HTML on the server.

It is possible to do this on page load by checking the URL however it is not advised as there is too much that can go wrong with that approach.

My advice is - render out the active class on the server when you render the page.
1

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Jeremy JohnsonAuthor Commented:
Many thanks for the explanation.
 
I can see now what I'm trying to achieve might be unnecessarily complicated for the result so will probably just ditch the active class all together!

Really grateful for your help, I'll accept as solution now.
0
Julian HansenCommented:
You don't necessarily ditch it - it is about where you apply it. Doing it in JavaScript for your purposes won't achieve what you want - but adding it on the server when you render the page will.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
CSS

From novice to tech pro — start learning today.