Add active class to current element

Jeremy Johnson
Jeremy Johnson used Ask the Experts™
on
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.
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
leakim971Multitechnician
Top Expert 2014

Commented:
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

Author

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
leakim971Multitechnician
Top Expert 2014

Commented:
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...
Ensure you’re charging the right price for your IT

Do you wonder if your IT business is truly profitable or if you should raise your prices? Learn how to calculate your overhead burden using our free interactive tool and use it to determine the right price for your IT services. Start calculating Now!

Author

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.
Most Valuable Expert 2017
Distinguished Expert 2018

Commented:
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

Author

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.
Most Valuable Expert 2017
Distinguished Expert 2018

Commented:
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.

Author

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?
Most Valuable Expert 2017
Distinguished Expert 2018
Commented:
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.

Author

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.
Most Valuable Expert 2017
Distinguished Expert 2018

Commented:
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.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial