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!
I think that you are mistaken jQuery and vanilla javascript
$.each is a jQuery function in you case you can use .forEach
$.attr is a jQuery function in you case you can use .getAttribute
const current = "#test-3";//window.location.href; document.querySelectorAll("#nav-tab a").forEach((elem) => { if (elem.getAttribute('href').indexOf(current) !== -1) { elem.classList.add("active"); } });
.active { color:red}
<div id="nav-tab"> <a href="#test-1">Test 1</a> <a href="#test-2">Test 2</a> <a href="#test-3">Test 3</a> <a href="#test-4">Test 4</a> </div>
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
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.