I am trying to add 'active' class on my link. It is saying
Uncaught TypeError: document.querySelectorAll(...).each is not a function
Here is my code:
const current = window.location.href;
document.querySelectorAll("#nav-tab a").each(function(){
const $this = this;
if($this.attr('href').indexOf(current) !== -1){
$this.classList.add("active");
}
});
Can you help me? Or is there a better way to add a class name based on the current URL? Thank you so much!
You have a few issues with your code. Your mainly confusing jQuery methods with regular native browser methods/conventions:
You need to use .forEach()
and not .each()
. The .forEach()
method is a method on the NodeList that querySelectorAll()
returns.
.attr()
is not a valid method. To get an element's attribute you can use .getAttribute()
. We can use .href
here instead to get the href. Note that getAttribute("href")
will retrieve the URL as it is in your mark-up, whereas .href
will retrieve the full, eg, if you had href="/foo/bar"
, .href
will give https://example.com/foo/bar
, whereas .getAttribute()
will return just /foo/bar
.
Use the element parameter of the function instead of this
. When you use .forEach()
you're iterating over the elements in your NodeList (ie: the elements you selected), so you can access each using the first parameter of the forEach
callback. The this
value in the browser (if not in strict mode) will default to window
, so it won't be the element like you're expecting it to be:
const current = window.location.href;
document.querySelectorAll("#nav-tab a").forEach(function(elem){
if(elem.href.includes(current)){
elem.classList.add("active");
}
});
I've also changed .indexOf(...) !== -1
to .includes()
, which is a more modern way to check if a string contains another value.
I will point out that you can make your query selector more advanced, which will limit the number of elements you iterate:
const current = window.location.href;
document.querySelectorAll(`#nav-tab a[href*="${current}"]`).forEach(elem => {
elem.classList.add("active");
});
This uses the attribute selector a[href*=...]
to select the a
elements that have a href
that contains the text in stored in current
.