I have a problem enabling the .active class for each menu item I click in the navbar of my website (which is built in HTML, CSS, JS).
I use a file nav.html to load the navbar in all my pages, with this code:
<header id="hero-header">
<script> AOS.init();
</script>
<div class="logo-container">
<a href="home.html"><img class="logo-desktop" id="logo-hero" src="assets/img/logo.svg"></a>
<a href="home.html"><img class="logo-mobile" id="logo-hero" src="assets/img/mobile-logo.svg"></a>
</div>
<ul>
<li data-aos="fade-down" data-aos-duration="600"><a href="home.html" class="menu-item-desktop">Home</a></li>
<!-- <li data-aos="fade-down" data-aos-duration="600"><a href="map.html" class="">Map</a></li> -->
<div data-aos="fade-down" data-aos-duration="800" class="menu-item-desktop dropdown">
<button class="dropbtn">LifePulse ID</button>
<div class="dropdown-content">
<a href="before-donation.html">Before Donation</a>
<a href="after-donation.html">After Donation</a>
<a href="how-else-can-I-help.html" class="">How else can I help</a>
</div>
</div>
<li data-aos="fade-down" data-aos-duration="1000"><a href="team.html" class="menu-item-desktop">Team</a></li>
<li data-aos="fade-down" data-aos-duration="1000"><a href="news.html" class="menu-item-desktop ">News</a></li>
<li data-aos="fade-down" data-aos-duration="1200"><a href="partners.html" class="menu-item-desktop ">Partners</a></li>
<li data-aos="fade-down" data-aos-duration="1400"><a href="contact.html" class="menu-item-desktop ">Contact</a></li>
<div data-aos="fade-down" data-aos-duration="1600" class="search-button">
<form action="/search">
<input type="search" name="q" id="search" placeholder="Type and click enter">
<a href="#" id="btn-close">
<span class="fontawesome-close">
<i class="fa-solid fa-times" style="color: #ffffff;"></i>
</span>
</a>
<a href="#" id="btn-search">
<span class="fontawesome-search">
<i class="fa-solid fa-magnifying-glass" style="color: #ffffff;"></i>
</span>
</a>
</form>
</div>
</ul>
<div class="button-container">
<a href="contact.html">
<div class="magnetic">
<div class="wrap">
<div class="span span-1 go"></div>
<div class="span span-2 go"></div>
<div class="span span-3 go"></div>
<div class="span span-4 go"></div>
<div class="span span-1 go"></div>
<img src="assets/img/hand.png">
</div>
</div>
</a>
</div>
</header>
<div id="hero-bottom">
<div class="city">Thessaloniki, GR</div>
<ul>
<a href="https://www.instagram.com/lifepulse_gr" target="_blank"><li><i class="fa-brands fa-instagram " style="color: #ffffff;"></i></li></a>
<a href="https://www.facebook.com/lifepulsegreece" target="_blank"><li><i class=" fa-brands fa-facebook-f social-icons fa-s" style="color: #ffffff;"></i></li></a>
<a href="https://www.linkedin.com/company/lifepulse-blood-donation" target="_blank"><li><i class="fa-brands fa-linkedin-in" style="color: #ffffff;"></i></li></a>
</ul>
</div>
I want each time I click on a menu item, this specific item to jump on active state. I tried creating a file menus.js with this code:
const links =document.querySelectorAll(".menu-item-desktop ");
links.forEach(btn => btn.addEventListener("click",(e)=>{
e.preventDefault();
btn.classList.add("active")
}));
and adding it at the bottom of the body tag in every html page, but it didn’t work. What am I missing?
2
Answers
If you want to click on links that replaces the page you are on with another page AND have the nav items to be active? Then you need to store what has been clicked in localStorage.
Alternatively load the HTML pages from the links using the same .load method you use for the nav.html
If not, then use delegation because that is a simpler way
You need to delegate from the nearest STATIC container- the one you load the nav into
Also since you load the nav menu using .load, you need the script that handles the clicks to NOT be in that file since JS will not run in an HTML page loaded using AJAX (which .load is).
This code needs to live in the page you load (external script is fine) and not in nav.html
Here is a jQuery version which will load the nav AND delegate
https://jsfiddle.net/x6ourewL/1/
Your issue is that the event handler code is running before the elements have loaded and thus does not add any events.
You have a number of options:
complete
callbackPutting your event handler code inside document load / doc.ready would not work as that would fire before your secondary load.
As provided in the comments, your code is currently (I’m assuming the event code is in the doc.ready, makes no difference)
Change this to add the event code inside the load callback:
Event delegation would be, using jquery as you’ve used jquery for doc/ready and load: