How can I get jQuery to compare an id
to an attribute and if matching add an .active
class to the element with the matching attribute?
I'm trying to refactor a long and repetitive jQuery code. I have set waypoints to trigger on scroll, once you reach a certain section it adds an active class to the menu link that refers to the section. This is the best I could manage, but it is not working.
$('section').waypoint(function(direction) {
if (direction === 'down') {
$('nav a').removeClass('active-nav');
var linkName = $('nav a').map( function() {
return $(this).attr('href');
}).get();
if(linkName == $('section[id]')){
$(this).addClass('active-nav');
}
}
}, {
offset: '25%'
});
The thinking behind this is that my section id
is the same as the href
value of the menu link (it's an anchor bookmark), so my logic is: Compare thesection id
to the nav a href
value, and if they match addClass .active
to this menu link. How can I achieve this logic?
a- How do I get the href
of all the links in nav
?
b- How do I then compare it to the section id
andaddClass
to the nav link that matches?
my html looks something like this:
<nav>
<a id="b1" href="#landing">Home</a>
<a id="b2" href="#portfolio">Portfolio</a>
<a id="b3" href="#experience">Experience</a>
<a id="b4" href="#about">About</a>
</nav>
<section id="landing">some content</section>
<section id="portfolio">some content</section>
<section id="experience">some content</section>
<section id="about">some content</section>
And my current jQuery looks like this
$('#landing').waypoint(function(direction) {
if (direction === 'down') {
$('nav a').removeClass('active-nav');
$('#b1').addClass('active-nav');
}
}, {
offset: '25%'
});
$('#landing').waypoint(function(direction) {
if (direction === 'up') {
$('nav a').removeClass('active-nav');
$('#b1').addClass('active-nav');
}
}, {
offset: '-25%'
});
Which works just fine but has to be repeated for every section individually.
Instead of using the id
of each section and attaching handlers, you can use the section
selector like this:
// this event is called for all sections.
$('section').waypoint(function(direction) {
if (direction === 'down') {
$('nav a').removeClass('active-nav');
// form the selector dynamically.
// "this" keyword refers waypoint object and the element is located at "this.element"
// using "this.element.id", get the nav anchor you want to target
// example: "nav a[href='#landing']"
var selector = "nav a[href='#" + this.element.id + "']";
$(selector).addClass('active-nav');
}
}, {
offset: '25%'
});
$('section').waypoint(function(direction) {
if (direction === 'up') {
$('nav a').removeClass('active-nav');
var selector = "nav a[href='#" + this.element.id + "']";
$(selector).addClass('active-nav');
}
}, {
offset: '-25%'
});
There are different ways to get the target element you want. In your case, since the section
and a
elements are in the same order, you can use .index()
and eq(n)
(Important: You need to wrap your sections with a div
for "index()
" to work.)
// this event is called for all sections.
$('section').waypoint(function(direction) {
if (direction === 'down') {
$('nav a').removeClass('active-nav');
$("nav a").eq($(this.element).index()).addClass('active-nav');
}
}, {
offset: '25%'
});
I have created a fiddle for the second way of doing. Test it and let me know.