This is how my code looks like:
<div class="header-nav navbar-collapse collapse ">
<ul id="navigation" class=" nav navbar-nav">
<li>
Home
</li>
<li>
About Us
</li>
</ul>
</div>
I've been trying to add the active class to each of them when the user is on that specific page but no succes so far
Tis is how my script looks like:
var i = 0;
[].forEach.call(document.querySelectorAll('li > a'), function(nav) {
console.log(nav.pathname,window.location.pathname);
if (nav.pathname === window.location.pathname){
i = 1;
console.log(i);
nav.classList.add('active')
}
else{
console.log(i)
nav.classList.removeClass('active')
}
})
The active class is set on the "a" not on "li" and i don't know how to fix this. Maybe someone can help me?
In looking at the classes, it looks like you may be using Bootstrap. I added in those libs to the snippet, and updated some of the classes. I also added in another nav item with the href equal to js since that is the pathname for the snippet window. Otherwise it won't add the active class as there would not be a pathname that would be equal.
I also changed the nav items to pills, so you can see the active link easier.
var i = 0;
document.querySelectorAll('ul.nav > li > a').forEach((nav) => {
console.log({
navPathname: nav.pathname,
windowLocationPathname: window.location.pathname,
areEqual: nav.pathname === window.location.pathname,
});
if (nav.pathname === window.location.pathname) {
nav.classList.add('active')
} else {
nav.classList.remove('active')
}
})
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
<div class="navbar navbar-light bg-light">
<ul id="navigation" class="nav nav-pills">
<li class="nav-item">
<a class="nav-link" href="index.html">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="js">JS</a>
</li>
<li class="nav-item">
<a class="nav-link" href="about-us.html">About Us</a>
</li>
</ul>
</div>
To target the parent element, you have a few options - my favorite is element.closest(selector) which takes a starting element and finds the closest containing parent that matches selector
let els = document.querySelectorAll('li > a');
els.forEach(el => {
el.addEventListener('click', e => {
els.forEach(a => a.closest('li').classList.remove('active'));
e.target.closest('li').classList.add('active');
})
})
li.active {
background-color: green;
}
<ul>
<li><a href='#'>link 1</a></li>
<li><a href='#'>link 1</a></li>
<li><a href='#'>link 1</a></li>
</ul>
Thanks for this, i merged the two responses and made it into one that works for me, this is the script that worked without even touching the classes into the nav-bar:
document.querySelectorAll('ul.nav > li > a').forEach((nav) => {
console.log({
navPathname: nav.pathname,
windowLocationPathname: window.location.pathname,
areEqual: nav.pathname === window.location.pathname,
});
if (nav.pathname === window.location.pathname) {
nav.closest('li').classList.add('active')
} else {
nav.closest('li').classList.remove('active')
}
})
Related
HTML code from menu:
<ul id="sidebarMenu" class="nav nav-sidebar" data-nav-type="accordion">
<li class="nav-item nav-item-submenu nav-item-expanded nav-item-open">
<i class="fad fa-user-tie fa-fw mr-2"></i>Webadmin
<ul class="nav nav-group-sub">
<li class="nav-item nav-item-submenu nav-item-expanded nav-item-open"><i class="fas fa-abacus mr-2"></i>tester
<ul class="nav nav-group-sub">
<li class="nav-item nav-item-submenu nav-item-expanded nav-item-open">
<i class="fas fa-abacus mr-2"></i>tester 2
<ul class="nav nav-group-sub">
<li class="nav-item">
<i class="fad fa-cogs fa-fw mr-2"></i>Site instellingen
</li>
</ul>
</li>
</ul>
</li>
<li class="nav-item"><i class="fad fa-list fa-fw mr-2"></i>Menu aanpassen</li>
</ul>
</li>
</ul>
What I want is add a class 'nav-item-expanded nav-item-open' on al related li with class nav-item-submenu.
So if the user is an a page that the menu collapse automatically the sub menus until the link
I have the next code:
This works. But its limited on my script this wil go back for 5 subs. But if the user want to use by example 6 menus the script fails. Sorry for my bad writing: D
$('.nav-item > a.active')
.closest('.nav-item-submenu')
.addClass('nav-item-expanded nav-item-open')
.parent()
.closest('.nav-item-submenu')
.addClass('nav-item-expanded nav-item-open')
.parent()
.closest('.nav-item-submenu')
.addClass('nav-item-expanded nav-item-open')
.parent()
.closest('.nav-item-submenu')
.addClass('nav-item-expanded nav-item-open')
.parent()
.closest('.nav-item-submenu')
.addClass('nav-item-expanded nav-item-open')
how can I simplify this code?
Example that I have tried:
var test = function(data = '') {
if (data === '') {
data = $('.nav-item > a.active').closest('.nav-item-submenu');
} else {
data = data.parent().closest('nav-item-submenu');
}
if (data.length > 0) {
data.addClass('nav-item-expanded nav-item-open');
test(data);
}
};
but that's not working.
You can use .parentsUntil() to simplify this. It returns all ancestors up to a point and can filter them. It takes two parameters:
Selector for the final ancestor to stop at.
Selector to filter the ancestors by.
This is almost the opposite of .find() which will traverse descendants instead. However, .find() will always work at any depth, it does not have a stop conditions like .parentsUntil().
A single call to .parentsUntil('#sidebarMenu', '.nav-item-submenu') will return all ancestor elements that you want - the .nav-item-submenu ones. At that point, you can add the classes you want or manipulate them further, if needed.
$('button').on('click', function() {
$('.nav-item > a.active')
.parentsUntil('#sidebarMenu', '.nav-item-submenu')
.addClass('nav-item-expanded nav-item-open');
})
.nav-item-submenu {
min-height: 50px;
padding: 5px;
border: 1px dashed black;
}
.nav-item-expanded {
border: 2px solid black;
}
.nav-item-open {
background-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul id="sidebarMenu" class="nav nav-sidebar" data-nav-type="accordion">
<li class="nav-item nav-item-submenu">
A
<ul class="nav nav-group-sub">
<li class="nav-item nav-item-submenu">B1
<ul class="nav nav-group-sub">
<li class="nav-item nav-item-submenu">
C
<ul class="nav nav-group-sub">
<li class="nav-item">
D
</li>
</ul>
</li>
</ul>
</li>
<li class="nav-item">B2</li>
</ul>
</li>
</ul>
<button>Click me</button>
This is a single-page website currently I am working on. But When I click another link in the navbar it's not changing color though hovering is working perfectly. Here is my html code :
<html>
<body>
<div class="collapse navbar-collapse justify-content-between" id="navbarSupportedContent">
<ul class="navbar-nav ms-auto mb-2 ">
<li class="nav-item ">
<a class="nav-link scroll active " aria-current="page" href="#intro">Home</a>
</li>
<li class="nav-item">
<a class="nav-link scroll" href="#about">About Us </a>
</li>
<li class="nav-item">
<a class="nav-link scroll" href="#services">Services</a>
</li>
<li class="nav-item">
<a class="nav-link scroll" href="#">Products</a>
</li>
</ul>
</div>
</html>
</body>
enter image description here
Here is my css:
<style>
.navbar .nav-item a {
color: #5cbf8f !important;
}
.navbar .nav-item a:hover {
color: #028b77 !important;
}
.navbar .nav-item a.active {
color: #028b77 !important;
}
</style>
enter image description here
Here is my Js :
<script>
$(document).ready(function () {
var scrollLink = $(".scroll");
// Smooth scrolling
scrollLink.click(function (e) {
e.preventDefault();
$("body,html").animate(
{
scrollTop: $(this.hash).offset().top,
},
1000
);
});
// Active link switching
$(window).scroll(function () {
var scrollbarLocation = $(this).scrollTop();
scrollLink.each(function () {
var sectionOffset = $(this.hash).offset().top - 20;
if (sectionOffset <= scrollbarLocation) {
$(this).parent().addClass("active");
$(this).parent().siblings().removeClass("active");
}
});
});
});
</script>
enter image description here
N.B: Don't really know about js, just found it on the internet.
Navbar:
enter image description here
I think your js is wrong.
$('.active').removeClass('active');
$(this).addClass('active');
More efficient options are available if the DOM hierarchy is known.
For example, if they're all siblings, you can use this:
$(this).addClass('active').siblings('.active').removeClass('active');
I have this one problem regarding the highlighted navbar menu which will only highlight when we clicked on it. For that to work, I'm using javascript. However, each pages has its own sub pages, for example, page Home has a link of local/home, but its content will lead to local/home/content. The sub link will not make the navbar to function The navbar was coded in different file, which I just extends in the home and other pages. I'm not very good at explaining but if I can elaborate more on any part I would do so. Below I attached my JS and my navbar:
Navbar :
<ul class="navbar-nav mr-auto" id="nav">
<li class="nav-item">
<a class="nav-link active" href="{{ url('/') }}">Home
<span class="sr-only">(current)</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ route('courses') }}">opportunities</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ route('events') }}">events</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ route('uqalc') }}">courses</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ route('contact') }}">contact</a>
</li>
</ul>
Javascript :
const currloc = location.href;
const menuItem = document.querySelectorAll('a');
const menuLen = menuItem.length;
for (let i = 0; i < menuLen; i++) {
menuItem[i].classList.remove('active');
if (menuItem[i].href === currloc) {
menuItem[i].className = "nav-link active";
}
}
Here, I add active class to the anchor tag which is inside .navbar-nav If the window location is https://www.google.com/index.html
then this code find an anchor tag which one inside the .navbar-nav if anchor tag href should be index.html then this code add class active to the anchor tag
function removeQueryString(url) {
return url.split('?')[0]
}
[].forEach.call(document.querySelectorAll('.navbar-nav a'), function(elem) {
if (removeQueryString(elem.href) === removeQueryString(window.location.href))
elem.classList.add('active')
else
elem.classList.remove('active')
})
I am developing a web page wherein I have header(containing the navigational menu) in separate html file say reusableheader.html and footer in separate file i.e. reusablefooter.html.
reusableheader.html:
<style>
.nav-menu a:hover, .nav-menu .active > a, .nav-menu li:hover > a {
color: #3fbbc0;
border-color: #3fbbc0;
}
</style>
<script>
$(function(){
var current_page_URL = location.href;
$( "a" ).each(function()
{
if ($(this).attr("href") !== "#")
{
var target_URL = $(this).prop("href");
if (target_URL == current_page_URL)
{
$("a").parent("li").removeClass("active");
$(this).parent("li").addClass("active");
return false;
}
}
});
});
</script>
<nav class="nav-menu d-none d-lg-block"> //set to fixed-top.
<ul>
<li class="active"><a class="nav-link" href="/hospital/">Home</a></li>
<li><a class="nav-link" href="/hospital/aboutus">About</a></li>
<li><a class="nav-link" href="/hospital/services">Services</a></li>
<li><a class="nav-link" href="/hospital/departments">Departments</a></li>
<li><a class="nav-link" href="/hospital/doctors">Doctors</a></li>
<li class="drop-down"><a class="nav-link" href="#">Reach Us</a>
<ul>
<li><a class="nav-link" href="/hospital/contact">Contact Us</a></li>
<li><a class="nav-link" href="#">Feedback</a></li>
<li><a class="nav-link" href="#">Blogs</a></li>
<li><a class="nav-link" href="#">Newsletters</a></li>
</ul>
</li>
</ul>
</nav><!-- .nav-menu -->
I am including the below javascript code in all my other web pages:
otherpages.jsp
<script>
$(function() {
$("#header").load("reusableheader.html");
});
</script>
The above code works fine i.e. on click of link on the menu item, its becomes the active link with the color assigned(in css) but when I scroll the page down, the activeness shifts from currently active link back to the "home" link.
What am I doing wrong here?
I think the problem is with removing the active class on the li element. How can you say $("a").parent("li").removeClass("active"); when you have got so many a elements with parent li element.
Instead, create a new for loop function which removes the element if the active class is found regardless of wherever it is in the list. And also add the logic on the click event of the li element, otherwise, it keeps looking for a URL match and changes it and would behave oddly if any path gets appended to the URL.
function removeClass() {
var listItems = $(".nav-menu > ul > li");
listItems.each(function (idx, li) {
$(li).removeClass("active");
});
}
I want to get the user url on my site. I want to show if the user url is the root domain, add active class to the id home-item-menu. If not, don't do nothing.
I was using window.location.href and window.location.host but didn't work.
For the rest of section's I was using indexof (and the string that the url has), but because the root domain don't have any string I don't know how to do it.
<nav class="cl-effect-5">
<li class="nav-item" id="home-item-menu">
<a class="nav-link menu-rucab js-scroll-trigger" href="#home"><span data-hover="HOME">HOME</span></a>
</li>
</nav>
<nav class="cl-effect-5">
<li class="nav-item" id="rucab-item-menu">
<a class="nav-link menu-rucab js-scroll-trigger" href="#rucab"><span data-hover="RUCAB">RUCAB</span></a>
</li>
</nav>
<nav class="cl-effect-5">
<li class="nav-item" id="inscripciones-item-menu">
<a class="nav-link menu-rucab js-scroll-trigger" href="#inscripciones"><span data-hover="INSCRIPCIONES">INSCRIPCIONES</span></a>
</li>
</nav>
<nav class="cl-effect-5">
<li class="nav-item" id="habitaciones-item-menu">
<a class="nav-link menu-rucab js-scroll-trigger" href="#habitaciones"><span data-hover="HABITACIONES">HABITACIONES</span></a>
</li>
</nav>
<nav class="cl-effect-5">
<li class="nav-item" id="staff-item-menu">
<a class="nav-link menu-rucab js-scroll-trigger" href="#staff"><span data-hover="STAFF">STAFF</span></a>
</li>
</nav>
<nav class="cl-effect-5">
<li class="nav-item" id="blog-item-menu">
<a class="nav-link menu-rucab js-scroll-trigger" href="#contact"><span data-hover="BLOG">BLOG</span></a>
</li>
</nav>
<nav class="cl-effect-5">
<li class="nav-item" id="contacto-item-menu">
<a class="nav-link menu-rucab js-scroll-trigger" href="#contacto"><span data-hover="CONTACTO">CONTACTO</span></a>
</li>
</nav>
JQuery/Javascript
$( document ).ready(
function() {
var url = window.location.href;
var host = window.location.host;
if(url.indexOf('http://' + host + '/') != -1) {
document.getElementById("home-item-menu").classList.add("active");
}
if (document.URL.indexOf("habitaciones") > -1)
{
document.getElementById("habitaciones-item-menu").classList.add("active");
} else if (document.URL.indexOf("contacto") > -1) {
document.getElementById("contacto-item-menu").classList.add("active");
} else if (document.URL.indexOf("rucab") > -1) {
document.getElementById("rucab-item-menu").classList.add("active");
} else if (document.URL.indexOf("inscripciones") > -1) {
document.getElementById("inscripciones-item-menu").classList.add("active");
} else if (document.URL.indexOf("staff") > -1) {
document.getElementById("staff-item-menu").classList.add("active");
} else if (document.URL.indexOf("blog") > -1) {
document.getElementById("blog-item-menu").classList.add("active");
}
});
You can use the condition window.location.pathname === '/':
if(window.location.pathname === '/') {
document.getElementById("home-item-menu").classList.add("active");
}
Hi #Pedro Corchero Murga you can use javascript sessions to achieve this set the text of the nav item to javascript session and get that session on load function and check the conditions if you don't familiar with javascript sessions you can see this link : https://www.w3schools.com/jsref/prop_win_sessionstorage.asp
First of all, define how you want to tell your application if this is my root URL, which one way to achieve this is as follows;
function isAtRoot () {
// Let's say you're currently at 'https://myhome.domain/',
// and this is your root.
var href = window.location.href,
urlWithoutQueryString = href.split('?')[0],
host = window.location.host,
regexp = new RegExp("^https?://" + host + "/?$", "i");
return !!urlWithoutQueryString.match(regexp);
}
Or you can also use window.location.pathname for this.
Then, run your javascript like above as follows,
if (isAtRoot()) {
document.getElementById("home-item-menu").classList.add("active");
}
However, I'd suggest that you have a list of paths for your site and give it an alias or name to it. Then, run something like isAtRoot against it instead, which will have more trust-able precision for future references.