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.
.forEach()not.each()(provided that your browser supports.forEach())forEachdocument.querySelectorAll("#nav-tab a").forEach(function(){Uncaught TypeError: Cannot read properties of undefined (reading 'attr')hmmm.getAttribute(), not.attr()(even using.hrefshould work)thisinside of your function also isn't going to be the lement. You want to access the element in your function using the argument of the functionfunction(elem) {, then call your methods oneleminstead of$this