How to add Active class based on page URL using Javascript - javascript

Sorry if this has been addressed before, but I'm very new to JS.
I'm using an example I've found here Add Active Class to a Navigation Menu Based on URL javascript - Works only when alert is given
My altered JS is here:
$(function() {
setTimeout(function(){
var pgurl = window.location.href.substr(window.location.href.lastIndexOf("/")+1);
console.log(pgurl);
$(".mega_menu ul li a").each(function(){
if($(this).attr("href") == pgurl || $(this).attr("href") == '' )
$(this).addClass("active");
});
}, 5000);
});
The console log is producing what appears to be the correct link however the active class is not being applied to the required class, I've included screenshots to hopefully help.console log displaying URL, NAV elements that ACTIVE class should be applied to.
Thank you in advance!

I thank everyone for your help. Below is the code that functions, and it's obvious that I have a way to go, in my understanding of JS:
$(function() {
setTimeout(function(){
var pgurl = window.location.href.substr(window.location.href.lastIndexOf("/")+1);
console.log(pgurl)
$("ul.mega_menu li a.mega_menu_with_ul").each(function(){
var _this = this;
console.log(_this)
//your condition fails here, can you check your pgurl has this value?
//old - if($(this).attr("href") == pgurl || $(this).attr("href") == '' )
// pgurl - hardcoded 'merchandise2.asp?Merchandise_Group1_ID=8' to run the code successfully
if($(_this).attr("href") == pgurl || $(_this).attr("href") == '' ) {
$(_this).addClass("active");
console.log(_this)
}
});
}, 50); });
I believe I was running into an issue in both the way the CSS calls were structured and my understanding of how specific I needed to be to address the correct element with Javascript.

Except pgurl, there is no issue with your code.
$(function() {
setTimeout(function(){
// var pgurl = window.location.href.substr(window.location.href.lastIndexOf("/")+1);
var pgurl = window.location.pathname.replace("/","") + window.location.search; //replace first "/" and make it empty
$("#nav ul li a").each(function(){
var _this = this;
//your condition fails here, can you check your pgurl has this value?
//old - if($(this).attr("href") == pgurl || $(this).attr("href") == '' )
// pgurl - hardcoded 'merchandise2.asp?Merchandise_Group1_ID=8' to run the code successfully
if($(_this).attr("href") == pgurl || $(_this).attr("href") == '' ) {
$(_this).addClass("active");
console.log(_this)
}
});
}, 50); });
Please note: you should not use getting and extracting the URL like this
window.location.href.substr(window.location.href.lastIndexOf("/")+1);
instead refer the easiest way to get url details
https://www.w3docs.com/snippets/javascript/how-to-get-current-url-in-javascript.html

Related

Check if a hash is the first element after first slash in href

I have a menu with links that may look like one of the following:
mywebsite.com/#find
mywebsite.com/about-us/#team
mywebsite.com/#social
mywebsite.com/services/#something
I want to do something only to the first and third links (the ones that don't have a subdirectory in the url path). How do I check if a # hash is the first element after the first slash in the link?
$('#menu a').click(function() {
var target = this.href;
// check if "/#" is the first thing after the domain name
});
Thank you.
The URL class that parse URLs can help you. URL.pathname property contain path of url (string after domain)
$('#menu a').click(function(e) {
if (new URL(this.href).pathname == "/"){
// Do something
}
});
More accurate mode is
$('#menu a').click(function(e) {
let url = new URL(this.href)
if (url.pathname == "/" && url.hash != ''){
// Do something
}
});
$('#menu a').click(function(e) {
e.preventDefault();
if (new URL(this.href).pathname == "/")
console.log("true");
});
a {display: block}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="menu">
mywebsite.com/#find
mywebsite.com/about-us/#team
mywebsite.com/#social
mywebsite.com/services/#something
</div>
Let's first ignore the https:// part then find the first / and hope to find a # after it.
var tests = `mywebsite.com/#find
mywebsite.com/about-us/#team
https://mywebsite.com/#social
mywebsite.com/services/#something`.split("\n");
function isMyHash(url) {
var start = url.indexOf("://") > -1 ? url.indexOf("://") + 3 : 0;
start = url.indexOf("/", start);
return (url.substring(start + 1, start + 2) == '#')
}
tests.forEach(function(test) {
console.log(test, isMyHash(test) ? "✔" : "x")
})

JS is included, but won't fire on load?

I have a js script that is supposed to fix my side menu on scroll. It shows it being included in the view source and if I copy/paste my code into console to auto-fire it, it works perfectly.
How can I figure out why it won't fire on load? No errors are thrown either. The file in question has 2 functions, the first is to fix the menu to to top and the second deals with changing content out by checking checkboxes.
Here is my script:
// FIX SIDE BAR AFTER SCROLL
$(window).load(function() {
console.log('test');
$("a[href*=#]:not([href=#])").click(function() {
if (location.pathname.replace(/^\//, "") == this.pathname.replace(/^\//, "") && location.hostname == this.hostname) {
var o = $(this.hash);
if (o = o.length ? o : $("[name=" + this.hash.slice(1) + "]"), o.length) return $("html,body").animate({
scrollTop: o.offset().top
}, 900), !1
}
});
console.log('test2');
$(window).load(function() {
var o = $(".sticky").offset().top,
t = function() {
var t = $(window).scrollTop();
t > o ? $(".sticky").addClass("stuck") : $(".sticky").removeClass("stuck")
};
t(), $(window).scroll(function() {
t()
});
console.log('test3');
});
//RADIO BUTTON CONTENT CHANGER
$(function(){
$('input[name="pricing-radios"]').on('change', function(){
if ($(this).val()=='pricing1') {
//change to "show update"
$(".pricing-engage-chng").text("179");
$(".pricing-engage-chng-additional").text(".01");
$(".pricing-crm-chng").text("214");
$(".pricing-crm-chng-additional").text(".01");
$(".upgrade-price").text(".0025");
} else if ($(this).val()=='pricing2') {
$(".pricing-engage-chng").text("699");
$(".pricing-engage-chng-additional").text(".005");
$(".pricing-crm-chng").text("714");
$(".pricing-crm-chng-additional").text(".006");
$(".upgrade-price").text(".0015");
} else if ($(this).val()=='pricing3') {
$(".pricing-engage-chng").text("3,499");
$(".pricing-engage-chng-additional").text(".0025");
$(".pricing-crm-chng").text("3,514");
$(".pricing-crm-chng-additional").text(".00325");
$(".upgrade-price").text(".00075");
}
});
});
});
My code seems to work in my JSFiddle and as I said, copy and pasting my code into my console will fire my command and yield the desired result.
You can see the live page here as well.
Thanks for the help!
Alright so I figured this out:
The framework we use has an auto-minify function in it. So when I pulled the old code through, this part is technically minified. So my vars were returning unknown elements.
$(window).load(function() {
var o = $(".sticky").offset().top,
t = function() {
var t = $(window).scrollTop();
t > o ? $(".sticky").addClass("stuck") : $(".sticky").removeClass("stuck")
};
t(), $(window).scroll(function() {
t()
});
I ended up rewriting a function to add the class and simplified it a little more and came up with this:
$(window).scroll(function() {
var scroll = $(window).scrollTop();
//if less than or = to 350 add class
if (scroll >= 350) {
$(".sticky").addClass("stuck");
// else remove class
} else {
$(".sticky").removeClass("stuck");
}
});
Now this one gets minified, but everything is predefined and is readable.

hasClass doesn't function as it should

I have a list of li items and would like to trigger a button click if 2 classes are found.
When a list item has 2 classes, I would like to trigger the btn with a click. Can you guys take a look for me?
The code:
<script type="text/javascript">
$(document).ready(function(){
var $html = $("#my-div ul li");
if ($html.hasClass("current") || $html.hasClass("extra")) {
$(".btn-1 a").click();}
else if ($html.hasClass("current") || $html.hasClass("extra2")) {
$(".btn-2 a").click();}
});
</script>
So one list item has class current + extra, and the other list item hasClass current + extra2.
Any idea what I am doing wrong here?
EDIT: Currently it does not work as should be.
It currently will always trigger ".btn-1" to click and does not look at the other statements. I think it just looks at the "current" class and not if also the "extra" or "extra2" class is in the same li item.
Try this:
<script type="text/javascript">
$(document).ready(function(){
var $html = $("#my-div ul li.current");
if ($html.hasClass("extra")) {
$(".btn-1 a a").click();}
else if ($html.hasClass("extra2")) {
$(".btn-2 a").click();}
});
</script>
The problem is, when you do $html.hasClass("current") || .. it would always evalutate to true and would not go to the else clause when node has a class current
You are making a comparison of a or b where you need a and b so change it to this:
<script type="text/javascript">
$(document).ready(function(){
var $html = $("#my-div ul li");
if ($html.hasClass("current") && $html.hasClass("extra")) {
$(".btn-1 a a").click();}
else if ($html.hasClass("current") && $html.hasClass("extra2")) {
$(".btn-2 a").click();}
});
</script>
Try replacing
$html.hasClass("current") || $html.hasClass("extra")
with
$html.hasClass("current") && $html.hasClass("extra")
and also
$html.hasClass("current") || $html.hasClass("extra2")
with
$html.hasClass("current") && $html.hasClass("extra2")
The original root of the problem is that you're using or (||) and not and (&&) when testing for classes. You're asking "if li has class current OR extra".
However, you can also refactor it a bit and make it a little cleaner as well:
// first, grab the <li> marked as current
var $current = $('#my-div ul li.current');
// test if we have a match and proceed
if ($current.size()){
// cache the final target selector (by initializing it to `false` we
// can later test and only execute the click when we have a match)
var target = false;
// now get in to second-level classes (can use either `.is()` or
// `.hasClass()` (thought I'd show an alternative method as well))
if ($current.hasClass('.extra')) target = '.btn-1 a a';
else if ($current.hasClass('.extra2')) target = '.btn-2 a';
// else if ($current.hasClass('...')) target = '...'; // more tests
// see if we found a match and click it
if (target) $(target).click();
}

window.location.href.match Not Working

Here is the code:
$(function() {
var pathname = (window.location.href.match(/[^\/]+$/)[0]);
$('#menu dl dd a#toparrow').each(function() {
if ($(this).attr('href') == pathname) {
$(this).addClass('currenttop');
}
});
});
Here is a link to my website: http://bluraymoviestore.com
The purpose of the script is to make the arrow image stay on the current page, like it does when you first click to the categories.
The script works when I'm clicked on the parent page, but when I click to the next page under the same category, the script no longer works (example: works with /bluraynewreleases but not /bluraynewreleases-2625374011-rc-2-new_releases.html). What do I need to add to the code to make it work?
Your regex doesn't match anything so it throws an error when you attempt to access [0] on it. Assuming your regex is correct this should fix the issue.
$(function(){
var matches = window.location.href.match(/[^\/]+$/);
if (matches && matches.length) {
var pathname = (matches[0]);
$('#menu dl dd a#toparrow').each(function() {
if ($(this).attr('href') == pathname) {
$(this).addClass('currenttop');
}
});
}
});

forward slash in menu stops active link from working - javascript controlled

I'm using a JS to activate the active link within a menu.
Problem is, my CMS places a forward slash before menu items. As soon as it does this, the JS no longer works. If I remove the slash, it works again.
Any ideas how I get it to work with and without the forward slash?
Here's a page I'm testing it on: http://www.sunseedor...k/products1.php
JS is:
$(function(){
var $page = jQuery.url.attr("file");
$('ul.top-nav li a').each(function(){
var $href = $(this).attr('href');
if ( ($href == $page) || ($href == '') ) {
$(this).addClass('on');
} else {
$(this).removeClass('on');
}
});
});
you might want to try this :
$(function(){
var currUrl = window.location.href;
if(currUrl.substr(-1) == "/")
jQuery.url.setUrl(currUrl.substr(0,currUrl.length-1));
var $page = jQuery.url.attr("file"); /* this comes as null
if the URL has ending slash*/
$('ul.top-nav li a').each(function(){
var $href = $(this).attr('href');
if ( ($href == $page) || ($href == '') ) { $(this).addClass('on'); }
else {
$(this).removeClass('on');
} });
});

Categories

Resources