Add a class if url is equal to href of a link - javascript

I'm trying to make a jQuery script in WordPress, that will add the "active" class to the element of my sidebar that has the same URL as the matching link in the navbar.
(function ($) {
var url = window.location.href;
$('.navbar-nav li').each(function ($) {
if ($('.navbar-nav li a').attr('href') == url) {
$('.navbar-nav li').addClass('active');
}
});
console.log(url);
})(jQuery);
.active {
background-color: black;}
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet"/>
<nav class="navbar fixed-top navbar-expand-lg navbar-dark bg-white">
<div class="collapse navbar-collapse" id="navbarTogglerDemo01">
<ul class="nav navbar-nav">
<li class="nav-item menu_accueil only-mobile">
<a class="nav-link" href="<?php echo get_site_url() ?>/">
Accueil
</a>
</li>
<li class="nav-item menu_marque">
<a class="nav-link" href="<?php echo get_site_url() ?>/la-marque-honey">
La marque
</a>
</li>
<li class="nav-item menu_formule">
<a class="nav-link" href="<?php echo get_site_url().'/la-formule-honey' ?>">
La formule
</a>
</li>
<li class="nav-item menu_bebe">
<a class="nav-link" href="<?php echo get_site_url() ?>/conseil">
Le monde de bébé
</a>
</li>
</ul>
</div>
</nav>
It shows an error ( $ is not a function ), while there's another piece of code on the website that works well with the same selectors.
What's the issue here ?
Thanks

It shows an error ( $ is not a function )
This error was because you were redefining $ inside the each as the element being iterated:
$('.navbar-nav li').each(function ($) {
// Dont do this -------------------^
There were a few things wrong with your code, but in general what you were doing was using selectors within the whole page instead of selectors with the current element being enumerated using each
$(function() {
var url = window.location.href;
$('.navbar-nav li').each(function() {
if ($('a',this).attr('href') == url) {
$(this).addClass('active');
}
});
console.log(url);
});
.active {
background-color: black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet" />
<nav class="navbar fixed-top ">
<div class="" id="navbarTogglerDemo01">
<ul class="nav navbar-nav">
<li class="nav-item menu_accueil only-mobile">
<a class="nav-link" href="xxx">
Accueil
</a>
</li>
<li class="nav-item menu_marque">
<a class="nav-link" href="xxx">
La marque
</a>
</li>
<li class="nav-item menu_formule">
<a class="nav-link" href="https://stacksnippets.net/js">
La formule
</a>
</li>
<li class="nav-item menu_bebe">
<a class="nav-link" href="xxx">
Le monde de bébé
</a>
</li>
</ul>
</div>
</nav>

You need to make sure your jquery script is loaded before your function is called. Just make sure the jquery script tag is before the script tag containing your code.
Aside from your initial error - what you have here will add .active to every li that's a child of .navbar-nav.
$('.navbar-nav li').each(function ($) {//So is $ in the function parenthisis
if ($('.navbar-nav li a').attr('href') == url) {
$('.navbar-nav li').addClass('active');//this is wrong
}
});
You should make use of the this keyword. Something like
$('.navbar-nav li').each(function () {
let anchor = $(this).children('a');
if ($(anchor).attr('href') == url) {
$(this).addClass('active');
}
});

Try this:
jQuery( document ).ready(function() {
var url = window.location.href;
$('.navbar-nav li').each(function ($) {
if ($('.navbar-nav li a').attr('href') == url) {
$('.navbar-nav li').addClass('active');
}
});
console.log(url);
});

Related

Select an element if the href value is a specific word

Hi and thanks in advance for your help!
I have previously used JS to add an active class to an element if the corresponding URL shows.
I am trying to take what I have done in the past and edit it.
I am trying to add an active class to an element if the href attribute equals '#tab1' for example. Rather than if the URL matches.
Please see the existing JS below that I am trying to work from, I have tried a few things including a getelementbyID rather than selecting the href but I'm lost.
$(document).ready(function () {
const $links = $('.hs-mega-menu ul li a');
$.each($links, function (index, link) {
if (link.href == (document.URL)) {
$(this).addClass('active');
}
});
});
An example of one of the nav-links I am trying to select and apply the active class too are below:
<li class="nav-item"> <a class="nav-link g-py-10--md g-px-15--md" href="#tab1" role="tab" data-toggle="tab">Printed Stationery<i class="g-ml-10 fa-solid fa-caret-down d-sm-none"></i></a> </li>
There are a few ways to do this, you can use a function like you have or you can filter or just use a selector for the attribute. Here are examples of the latter two.
$(function() {
let testurl = "#tab1";
const $links = $('.hs-mega-menu ul li a');
$links.filter(function(index, link) {
return $(this).attr('href') == testurl;
}).addClass("active");
$links.filter("[href='" + testurl + "']").addClass("active-test")
});
.active {
color: green;
}
.active-test {
background-color: #ffddff;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="hs-mega-menu">
<ul>
<li class="nav-item"> <a class="nav-link g-py-10--md g-px-15--md" href="#tab1" role="tab" data-toggle="tab">Printed Stationery<i class="g-ml-10 fa-solid fa-caret-down d-sm-none"></i></a> </li>
<li class="nav-item"> <a class="nav-link g-py-10--md g-px-15--md" href="#tab1" role="tab" data-toggle="tab">Printed Stationery<i class="g-ml-10 fa-solid fa-caret-down d-sm-none"></i></a> </li>
<li class="nav-item"> <a class="nav-link g-py-10--md g-px-15--md" href="#tab2" role="tab" data-toggle="tab">Printed Stationery<i class="g-ml-10 fa-solid fa-caret-down d-sm-none"></i></a> </li>
</ul>
</div>

Add active class after page loading

I am trying to add an active class after page load. Here is my script. This script is working when I click. But when the page is loaded, the active class disappear.
<ul class="navbar-nav bg-gradient-primary sidebar sidebar-dark accordion" id="accordionSidebar">
<li class="nav-item">
<a class="nav-link" href="{{url('/account')}}" target="_blank">
<i class="fas fa-fw fa-tachometer-alt"> account</i>
</li>
</ul>
$(document).ready(function(){
$(".nav-item a").on("click", function(){ $(".nav-item").find(".active").removeClass("active"); $(this).parent().addClass("active");});
});
I am trying to work with localStorage function not succeed .please suggest me what I have to do.
You can clean up your code in many ways:
use toggleClass instead of add/remove class
use .nav-link rather than .nav-item a for one, a will be any anchor element, not just the first child (you'd do better to do .nav-item > a), but that has a distinctive class (.nav-link) so use that
to assign a class on load, just do it and don't put it in the click event
$(document).ready(function() {
$('.nav-item').addClass('active'); // <-- how to add the class on page load
$(".nav-link").on("click", function() {
$(this).parent().toggleClass('active');
});
});
.active .nav-link::after {
content: " <==";
color: red;
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
<div class="container">
<ul class="navbar-nav bg-gradient-primary sidebar sidebar-dark accordion" id="accordionSidebar">
<li class="nav-item">
<a class="nav-link" href="{{url('/account')}}" target="_blank">
<i class="fas fa-fw fa-tachometer-alt"> account</i>
</a>
</li>
</ul>
</div>
You can check if the url has the href or not then you can trigger the click event for the <a> which has matched href ..
Try the next code
<ul class="navbar-nav bg-gradient-primary sidebar sidebar-dark accordion" id="accordionSidebar">
<li class="nav-item">
<a class="nav-link" href="{{url('/account')}}" target="_blank">
<i class="fas fa-fw fa-tachometer-alt"> account</i>
</a>
</li>
</ul>
$(document).ready(function(){
$(".nav-item a").on("click", function(){
$(".nav-item.active").removeClass("active");
$(this).parent().addClass("active");
}).filter(function(){
return window.location.href.indexOf($(this).attr('href').trim()) > -1;
}).click();
});
Note about the code above ^^^^^:
The code above won't work as expected IF you have url http://website.com/account/thing and you have two <a> with hrefs /account and /account/thing both of <a> will get selected
To avoid this you can use data attribute
<ul class="navbar-nav bg-gradient-primary sidebar sidebar-dark accordion" id="accordionSidebar">
<li class="nav-item">
<a class="nav-link" href="{{url('/account')}}" data-href="http://website.com/account" target="_blank">
<i class="fas fa-fw fa-tachometer-alt"> account</i>
</a>
</li>
</ul>
$(document).ready(function(){
$(".nav-item a").on("click", function(){
$(".nav-item.active").removeClass("active");
$(this).parent().addClass("active");
}).filter(function(){
return window.location.href == $(this).attr('data-href').trim();
}).click();
});
Note about the code above ^^^^^:
In <a> add data-href="http://website.com/account" replace http://website.com/account with the full url

How to manage more effectively html button click events?

It looks ridiculous to do so many tasks on a button click while every button should have its own events:
function allStories() {
$('#zero-md').hide();
$('.container-aboutme').hide();
$('.container-allstories').show();
$('.container-allstories').load("pages/allstories.html");
$("#home").removeClass("nav-link active").addClass("nav-link");
$("#aboutme").removeClass("nav-link active").addClass("nav-link");
$("#allposts").removeClass("nav-link").addClass("nav-link active");
}
function aboutMe() {
$('#zero-md').hide();
$('.container-allstories').hide();
$('.container-aboutme').show();
$('.container-aboutme').load("pages/about.html");
$("#home").removeClass("nav-link active").addClass("nav-link");
$("#allposts").removeClass("nav-link active").addClass("nav-link");
$("#aboutme").removeClass("nav-link").addClass("nav-link active");
}
<li class="nav-item">
<a class="nav-link" id="allposts" onclick="allStories()" href="#">All posts</a>
</li>
<li class="nav-item">
<a class="nav-link" id="aboutme" onclick="aboutMe()" href="#">About me</a>
</li>
Is there is a better, more effective way to organize such events with less code?
You mean this
$("#nav").on("click",".nav-link",function(e) {
e.preventDefault(); // stop the link
const id = this.id;
const $thisContainer = $('.container'+id);
$('#zero-md').hide();
$('.container').hide(); // hide all containers
$thisContainer.load("pages/"+id+".html",function() { // perhaps not load if already loaded
$thisContainer.fadeIn("slow");
}) ;
$(".nav-link").removeClass("active")
$(this).addClass("active")
})
<ul id="nav">
<li class="nav-item">
<a class="nav-link" id="allposts" href="#">All posts</a>
</li>
<li class="nav-item">
<a class="nav-link" id="about" href="#">About me</a>
</li>
</ul>
Yes. Try to keep your code DRY (don't repeat yourself.)
Add an event listener in your JS.
Use e.target to determine what was clicked.
Chain your commands together when they're operating on the same elements.
Don't remove a class and then add the same class back. Just remove the one you want to get rid of.
I've added some stand in elements since not everything was present in your HTML.
$('.nav-link').click( (e)=>{
let theLink = $(e.target).attr('id');
const container = '.container-'+$(theLink).attr('id');
$('#zero-md').hide();
$('.container').hide();
$(container).show().load("pages/"+theLink+".html");
alert('loading: pages/'+theLink+'.html');
$("#home").removeClass("nav-link active").addClass("nav-link");
$(".nav-link").removeClass("active");
$("#"+theLink).addClass("active");
});
.active {
font-size: 1.5rem;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<li class="nav-item">
<a class="nav-link" id="allstories" href="#">All posts</a>
</li>
<li class="nav-item">
<a class="nav-link" id="aboutme" href="#">About me</a>
</li>
<div class="container container-allstories">All Stories</div>
<div class="container container-aboutme">About Me</div>
<div id="zero-md">Zero MD</div>

How to select 2nd bootstrap tab on load of page?

EDIT: So i ditched the whole thing and resorted to javascript with these new codes #Udara Kasun's code worked and it was close but not what I was trying to achieve. tried these codes for a while and i think i almost got it.
<script>
function myFunction1()
{
$(document).ready(function()
{
$('.nav-tabs li:nth-child(1) a').tab('show')
});
}
function myFunction2()
{
$(document).ready(function()
{
$('.nav-tabs li:nth-child(2) a').tab('show')
});
}
function myFunction3()
{
$(document).ready(function()
{
$('.nav-tabs li:nth-child(3) a').tab('show')
});
}
</script>
<li role="presentation" class="active" id="tabMenu1" onclick="myFunction1()">
<a href="#tabZone" data-toggle="tab" role="tab" aria-controls="tab1">
Zones
</a>
</li>
<li role="presentation" id="tabMenu2" onclick="myFunction2()">
<a href="#tabChapels" data-toggle="tab" role="tab" aria-controls="tab2">
Chapels
</a>
</li>
<li role="presentation" id="tabMenu3" onclick="myFunction3()">
<a href="#tabUnits" data-toggle="tab" role="tab" aria-controls="tab3">
Units
</a>
</li>
Did you try to do like this?
$(document).ready(function(){
$('.nav-tabs a:last').tab('show') ;
var lastselectedtab = localStorage.getItem("ActiveTab");
$('.nav-tabs a[href="'+(lastselectedtab==''?"#tabChapels":lastselectedtab)+'"]').tab('show');
});
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
var target = $(e.target).attr("href") // activated tab
localStorage.setItem("ActiveTab", target);
})
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script><script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<div role="tabpanel">
<ul class="nav nav-tabs" role="tablist">
<li role="presentation">
Zones
</li>
<li role="presentation">
Chapels
</li>
</ul>
<div id="tabContent1" class="tab-content" style="font-family:Arial Unicode MS;">
<div role="tabpanel" class="tab-pane fade" id="tabZone">
Content 1
</div>
<div role="tabpanel" class="tab-pane fade in active" id="tabChapels">
Content 2
</div>
</div>
</div>
Code pen Link
https://codepen.io/udarakasun/pen/YdyRRy
Nobody seemed to care anymore haha anyways for those of you who are wanting to achieve the same thing that I wanted to, I've created a stupid and ingenious way but it works.
<script language="javascript">
<?php
if(isset($_GET['tabName']))
{
if($_GET['tabName']=="TAB1")
{
echo "var tabNo=1;";
$_SESSION['tabNo']=1;
}
elseif($_GET['tabName']=="TAB2")
{
echo "var tabNo=2;";
$_SESSION['tabNo']=2;
}
}
?>
function loadscript()
{
$(document).ready(function()
{
$('.nav-tabs li:nth-child('+<?php echo $_SESSION['tabNo'];?>+') a').tab('show')
});
}
function myFunction1()
{
var tabName="TAB1";
window.location.href = "panel_gkkmain.php?tabName=" + tabName;
}
function myFunction2()
{
$(document).ready(function()
{
$('.nav-tabs li:nth-child(2) a').tab('show')
});
var tabName="TAB2";
window.location.href = "panel_gkkmain.php?tabName=" + tabName;
}
function myFunction3()
{
var tabName="TAB3";
window.location.href = "panel_gkkmain.php?tabName=" + tabName;
}
and for the body, you have to declare onload="loadscript()"
After that you'll need to add bootstrap components to your page. This can be done easier through ADOBE DREAMWEAVER.
<ul class="nav nav-tabs" role="tablist">
<li role="presentation" class="active" onClick="myFunction1()">
<a href="#home1" data-toggle="tab" role="tab" aria-controls="tab1">
Zones
</a>
</li>
<li role="presentation" onClick="myFunction2()">
<a href="#paneTwo1" data-toggle="tab" role="tab" aria-controls="tab2">
Chapels
</a>
</li>

jQuery adding active class to navbar doesnt work

So instead of adding an active class to the navbar using HTML I instead wanted to add it through jQuery but my code doesn't seem to work.
$('.navbar-nav li a[href="' + location.pathname + '"]').addClass('active');
<nav>
<ul class="navbar-nav">
<li class="nav-item" >
<a class="nav-link active" href="">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="">Wat is het?</a>
</li>
</ul>
</nav>
Can anybody help me out?
I think what do you need is window.location.href.
Something like this:
var pathname = window.location.href;
$('.navbar-nav li a').attr('href',pathname).addClass('active');
Check this example: https://jsfiddle.net/tbx56gtL/7/
Maybe you can do it like this:
$(function() {
var currentLoc = window.location.href;
if(/PageYouWant/.test(currentLoc) {
$('.navbar-nav li a').addClass('active');
}
});
If you want to set active in anchor tag you can do one of the following options.
Asign ids to every a tag
Asign a data attrib and add a class toggleClassX
Use $(this).addClass("active")
The following are the examples of each recomendation :
1 html:
<nav>
<ul class="navbar-nav">
<li class="nav-item" >
<a class="nav-link active" id="myId1" href="">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" id="myId2" href="">Wat is het?</a>
</li>
</ul>
</nav>
2 html:
<nav>
<ul class="navbar-nav">
<li class="nav-item" >
<a class="nav-link toggleClass1 active" data-tclass="1" href="">Home</a>
</li>
<li class="nav-item">
<a class="nav-link toggleClass2" data-tclass="2" href="">Wat is het?</a>
</li>
</ul>
</nav>
3 html: your structure is ok for the last example
1 js:
$("element").click(function(){
$("#myId1").addClass("active")
});
2 js:
$(".nav-link").click(function(){
var tclass = $(this).data("tclass)
$(".toggleClass"+tclass).addClass("active")
});
3 js:
$(".nav-link").click(function(){
$(this).addClass("active")
});
Hope the above answer your question.

Categories

Resources