Add active class to parent nav when on child pages - javascript

I need to highlight the parent nav item when a user is within a child page based on the URL.
User is currently on the page foo1-child and the parent is foo1 so I need to add the active class to Foo 1: http://foo.com/foo1/foo1-child.html
NAV:
<ul class="main-nav">
<li>Foo 1</li>
<li>Foo 5</li>
</ul>
I have no issue adding an active class to links within the nav as I just compare every the href in the .nav li a vs the URL but how can I check the URL for a matching anchor link name in the URL or something similar?
Current JS
$('.main-nav li > a').each(function () {
var $this = $(this);
if ($this.attr('href').indexOf(location.pathname) !== -1) {
$this.addClass('active');
}
});

If you cut off the ".html" from the end of both of them and you search for the a's href (which should be shorter) in the location, it should work.
$('.main-nav li > a').each(function () {
var $this = $(this);
var loc = location.
if (location.pathname.replace(/\/[^\/]*\.html$/, '').startsWith($this.attr('href').replace(/\.html$/, ''))) {
$this.parent().addClass('active');
}
});
You can see it in "action" here: https://jsfiddle.net/c8u2f91v/ Note it uses a fake location_pathname instead of location.pathname, because jsfiddle doesn't have the necessary prefixes in the path, but it shows that it should work.

Related

How to check if url contains parent page url?

I want to check if the current url contains the parent url to add an "active" class to the parent list item link.
jQuery(function($) {
var path = window.location.pathname;
$('ul a').each(function() {
if (this.pathname.indexOf( path )) {
$(this).addClass('active');
}
});
});
My html looks like this:
<ul>
<li><a class="list-link">Posts</a></li>
<li><a class="list-link">Blog</a></li>
<li><a class="list-link">Contact</a></li>
</ul>
When going to domain.com/contact/email I want to keep the list item to keep the "active" class.
If I understand your question correctly, you're wanting to add the active class to anchor elements in your ul list, if the anchor's text exists in the current browser path.
That can be achieved via the following (see documentation in snippet for details):
jQuery(function($) {
//var path = window.location.pathname;
var path = 'domain.com/contact/email';
// Convert path to lower case for easier matching
path = path.toLowerCase();
$('ul a').each(function() {
// Extract link label via text() method. Convert
// label to lower case for easier matching
var label = $(this).text().toLowerCase();
// Use indexOf() to check for label existing in
// path
if( path.indexOf(label) !== -1 ) {
// Add active class if match found
$(this).addClass('active');
}
});
});
.active {
background:red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<ul>
<li><a class="list-link">Posts</a></li>
<li><a class="list-link">Blog</a></li>
<li><a class="list-link">Contact</a></li>
</ul>
UPDATE
I found what I was looking for using this jQuery code:
jQuery(function($) {
var path = window.location.pathname.split( '/' )[2];
$('ul a').each(function() {
if (this.href.indexOf( path ) != -1) {
$(this).addClass('active');
}
});
});
Anchors don't have a pathname property. Change the line to check the text contained within the anchor:
if (this.textContent.indexOf( path )) {

active class on menu and parent item

i have this HTML code for my menu:
<nav id="main-navigation" class="navigation-simple">
<ul>
<li>Home</li>
<li><a class="active-nav" href="">About Us</a>
<ul>
<li><a class="active-nav" href="about">About</a></li>
<li>Testimonials</li>
<li>Meet The Team</li>
</ul>
</li>
</nav>
i have added in the active-nav class but how can i automatically set the active class on parent and child items when the current URL is the href value of the link?
you need java script for this, jQuery is great for beginners!
It could be done like this:
var url = window.location.href;
$( "nav li a" ).each(function(index) {
if (url.indexOf($(this).attr('href')) >= 0){
$(this).addClass('active-nav');
}
});
line by line -
get the current page url
for each link in the navigation...
check if its href is in the current url
if it is, add the class 'active-nav'
close if statement
close for loop
You can use the .filter() method to find the appropriate link and add the required class:
$('#main-navigation li > a').removeClass('active-nav')
.filter(function() {
return location.href.indexOf(this.href) > -1;
})
.addClass('active-nav') //add class to matched element(s)
//add class to parent(s) of matched, if any
.each(function() {
$($(this).parents('a'), '#main-navigation').addClass('active-nav');
});
Also remember to close your first ul.
Something like:
$(function() {
$('#main-navigation a').each(function() {
if(this.href.indexOf(window.location.pathname) === 0) {
$(this).addClass('active-nav');
} else {
// case when something was set to active by the server
$(this).removeClass('active-nav');
}
});
});
will do the job.
Make sure you make the if condition safe to your sites deeplinking implementation (e.g. GET params, anchors or multiple domains with same pathname are possible within your navigation).

Apply the class "active" to nav links when clicked?

My website is a parallax one page scrolling website, so all my nav links are directed to ids nested within that page...
For example:
<ul class="clearfix">
<li>Home</li>
<li>Work</li>
<li>About</li>
<li>Contact</li>
</ul>
So How would I tell my html that when someone clicks on one of these links and directs them to the corresponding ID on the page, to take on the class active? And the link that was active to turn back to the regular styling?
Assuming your link elements are contained in an element with class nav, and you're using jQuery, you could do the following:
$('.nav a').on('click', function(event) {
$('.nav a.active').removeClass('active');
$(this).addClass('active');
});
fiddle
You will have to use JavaScript to add that functionality into your application. Everytime a link is clicked, add the 'active' class to the triggering element, and remove it from all others. This is straightforward if you can use jQuery (jsFiddle with jQuery), and only a little more tedious otherwise.
$(function() {
$("ul.clearfix > li > a").click(function() {
$("a.active").removeClass("active");
$(this).addClass("active");
});
});
If you're only using native JS, you can try something along the lines of the below (jsFiddle using vanilla JS):
var links = document.getElementsByTagName("a"); // more specific selector if other links
for (var i = 0; i < links.length; i++) {
var link = links[i];
link.onclick = function () {
var prev = document.getElementsByClassName("active");
if (prev && prev[0]) {
prev[0].className = ""; // if using other classes, filter better
}
this.className += " active";
};
}
This second solution needs to be adapted to fit your particular application/DOM structure, since it's not quite as flexible as the first.
jQuery
$('ul a').on('click', function(event) {
$('a').removeClass("active");
$(this).addClass("active");
});
Replace ul a with something more specific like .nav a

dynamically apply active class to nav li

I have included a header to my files as in include. In the header is the nav bar.
How do I, using jQuery, apply class="active" to the relevant li.
The only way I could think of doing it is to set a variable on the actual pages, apply an id that is equal to that variable of the relevant page and if function so if they match apply a class to the li.
However, I thought there must be a simpler way of achieving this.
<ul class="nav nav-pills right" id="div">
<li id="home" class="active">
Home
</li>
<li id="search">
Search
</li>
<li id="contact">
Contact
</li>
</ul>
An easy way to do this would be to have a script per page:
$('#home').addClass('active'); // for home page
You could try and match the href to the current url:
var path = window.location.pathname.substring(1);
$('.nav>li>a[href="' + path + '"]').parent().addClass('active');
More compact way:
$(function(){
var sPath = window.location.pathname;
var sPage = sPath.substring(sPath.lastIndexOf('/') + 1);
$('a[href="'+ sPage +'"]').parent().addClass('active');
});
As soon as the page loads it will run this code:
$(document).ready(function(){
$('li').removeClass('active');
$('li a').each(function() {
$found = $.contains($(this).prop("href"),location.pathname);
if ($found) {
$(this).closest('li').addClass('active');
break;
}
});
});
OR
You can also do this using regex :
$(document).ready(function(){
$('li').removeClass('active');
var regex = /[a-z]+.php/g;
var input = location.pathname;
if(regex.test(input)) {
var matches = input.match(regex);
$('a[href="'+matches[0]+'"]').closest('li').addClass('active');
}
});
You might need to have the similar id name to that of php file.
Check the demo here : Demo
You can do this:
//remove the active class from all items, if there is any
$('.nav>li').removeClass('active');
//finally, add the active class to the current item
$('a[href='+ location.pathname.substring(1) +']').parent().addClass('active');
You could use javascript to find the current list item based on the url, by adding the class to the right list item after the DOM has been loaded (e.g. string manipulation of window.location together with JQuery selectors and addClass())
I found a routine to set active (current) class on my shared menu, but I need to modify it to set the parent link only, and not the 'closest' link. It works great on menu items with no sub menus, but when a sub menu item is clicked, there is not indication on the main menu after page load. (the code I need to modify is below)
(function( $ ) {
$.fn.activeNavigation = function(selector) {
var pathname = window.location.pathname
var extension_position;
var href;
var hrefs = []
$(selector).find("a").each(function(){
// Remove href file extension
extension_position = $(this).attr("href").lastIndexOf('.');
href = (extension_position >= 0) ? $(this).attr("href").substr(0, extension_position) :
$(this).attr("href");
if (pathname.indexOf(href) > -1) {
hrefs.push($(this));
}
})
if (hrefs.length) {
hrefs.sort(function(a,b){
return b.attr("href").length - a.attr("href").length
})
hrefs[0].closest('li').addClass("current")
}
}; })(jQuery);
If someone still checks on google how to do it here is my solution
var path = window.location.href; // full url
$('a[href="'+ path +'"]').parent().addClass('active'); // find by selector url
HTML
<ul class="navbar-nav mr-auto">
<li class="nav-item">
<a class="nav-link" href="http://example.com/">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="http://example.com/history"> History</a>
</li>
</ul>

Toggle css class using Jquery

I have a standard ul-based CSS navigation menu. I'm trying to use Jquery to toggle the active menu css class name. However, I'm encountering two issues:
The window.location.href never equals any of my anchor hrefs. I switched to pathname, but they still do not match each other. Even though in the debugger they appear to.
I cannot seem to get the li from it's anchor.prev. I need to change the class name on the li.
Here's the html:
<div id="left-content">
<ul>
<li class="separator">Main
<ul>
<li class="active link">Main 1</li>
<li class="link">Main 2</li>
<li class="link">Main 3</li>
</ul>
</li>
<li class="separator">Tools
<ul>
<li class="link">Tools 1</li>
</ul>
</li>
</ul>
</div>
When an anchor is clicked, it's corresponding li should have "active link" as the class name. And all other li's should be reset to just "link" as the class name.
Here's the Jquery javascript:
function toggle_active_menu() {
$('#left-content a').each(function() {
/*var isActive = $(this).attr('href') == window.location.href;*/
var active = this.pathname == window.location.pathname;
var prev = this.prev();
alert("active: " + active + "\nthis.pathname: " + this.pathname + "\nwindow.location.pathname: " + window.location.pathname + "\nprev: " + prev);
prev.toggleClass('active', active);
});
}
I put the alert in there to help debug. As I mentioned, the clicked anchor's href (or pathname) never matched the window's location href (or pathname). And prev is always undefined instead of being the li of the anchor.
Eventual Answer
After testing the various answers, I fould that I had to remove the onclick calls and call the toggle_active_menu function in the document ready function instead. The window location was not being updated before onclick was being called. Also, I did not use toggleClass so that I could preserve the order of the class names.
function toggle_active_menu() {
$('#left-content ul li ul li a').each(function() {
var pathname = window.location.pathname == '/' ? '/main1' : window.location.pathname;
var active = pathname.indexOf(this.pathname) != -1;
if (active) {
$(this).parent().attr('class', 'active link');
} else {
$(this).parent().attr('class', 'link');
}
});
}
To get the li which is the parent of a element use parent method and toggleClass take only the calss to toggle. To compare the href of the anchor with window.location.href you can use indexOf method.
function toggle_active_menu() {
$('#left-content a').each(function() {
var isActive = (window.location.href.toLowerCase().indexOf($(this).attr('href')) != -1);
$(this).parent().toggleClass('active');
alert("active: " + isActive);
});
}
Simplified version for you.
$('.link').click(function(){
$('.link').removeClass('active');
$(this).addClass('active');
})
toggleClass only takes one paramater it should be
prev.toggleClass('active');
To fix getting a handle on the correct LI to toggle the class, try
var prev = $(this).parent();
For the pathname, try using $(this).attr("href") and matching it against window.location.href, or checking if it's contained within window.location.href

Categories