Reputation: 283
This is the fiddle: https://jsfiddle.net/c1d3tfnL/
It is a big HTML code but the only things that matter are the section names and the side nav at the top. With this jQuery code :
$(window).scroll(function(){
var cutoff = $(window).scrollTop();
panel.each(function(){
if($(this).offset().top + $(this).height() > cutoff){
panel.removeClass('current');
$(this).addClass('current');
return false;
}
})
var aChildren = $('.side ul').children();
var aArray = [];
for (var i=0; i < aChildren.length; i++) {
var aChild = aChildren[i];
var ahref = $(aChild).attr('id');
aArray.push(ahref);
}
for (var i=0; i < aArray.length; i++) {
var theID = aArray[i];
if (panel.hasClass('current')) {
$("a[href='#" + theID + "']").addClass('greens');
} else {
$("a[href='#" + theID + "']").removeClass('greens');
}
}
I am supposed to add class greens
to the section that has a class current
. But the class greens
appears on every section. I am nor sure where is the problem.
I added this:
if (panel.hasClass('current')) {
$("a[href='#" + theID + "']").addClass('greens');
} else {
$("a[href='#" + theID + "']").removeClass('greens');
}
But it is just ignoring the code. Any thoughts? I know the fiddle is a bit messy but I can't sent everything here as there are many parts on the private server.
Upvotes: 0
Views: 61
Reputation: 1515
Let me know if I'm anywhere near where you need help -- the main goal was to try and replicate what you've described. However, instead of looping through the children elements of a panel, this code is leaning on CSS to target the children elements for us. (So, really the meat of this response is found in the CSS section of the code snippet).
If you know that your panel has the class .current
; using CSS you can target the children anchor tags by writing:
.panel.current a{
background-color: green;
}
Saves your code (and sanity) from trying to capture and loop through each chunk of children elements.
(Sorry that my code example is in Vanilla JavaScript -- it has been a long time since I've been in jQuery)
// get all of the elements with the class .panel
const panelNodeList = document.getElementsByClassName('panel');
// convert the NodeList of panels into a proper array
const panels = [...panelNodeList];
// assign the classname .current to the first panel (on load)
panels[0].classList.add('current');
// since the position of the .panel elements won't change,
// saving the top position(s) in an array just to save a
// a little processing time
let offsets = panels.map( panel => panel.getBoundingClientRect().top );
// listen to the scroll event on the window element
window.addEventListener('scroll', function(e){
// get the scrollY position of the window (and add 10px to
// give the elements some breathing room)
let pos = window.scrollY + 10;
// remove the .current class from all the panels
panels.forEach( panel => panel.classList.remove('current') );
// compare the scroll position of the window vs. the
// panel element(s) top offset
// go through the array list in reverse to stop execution
// when the first match is found (instead of trying to
// compare against the next element in the array)
for( let i=offsets.length, x=0; i>=x; i-- ){
if( pos > offsets[i] ){
// if the scroll position is greater than the
// offset, then it's the most top element visible
// add the class .current
panels[i].classList.add('current');
// break -- to stop the loop
break;
}
}
});
.panel{
padding: 10px;
margin: 5px;
border: solid 1px black;
}
.panel a{
display: block;
}
.panel.current{
background-color: #333333;
}
.panel.current a{
color: green;
}
<div class="panel">
<a href="#">lorem</a>
<a href="#">ipsum</a>
<a href="#">lorem</a>
<a href="#">ipsum</a>
<a href="#">lorem</a>
<a href="#">ipsum</a>
</div>
<div class="panel">
<a href="#">lorem</a>
<a href="#">ipsum</a>
<a href="#">lorem</a>
<a href="#">ipsum</a>
</div>
<div class="panel">
<a href="#">lorem</a>
<a href="#">ipsum</a>
</div>
<div class="panel">
<a href="#">lorem</a>
<a href="#">ipsum</a>
<a href="#">lorem</a>
<a href="#">ipsum</a>
</div>
<div class="panel">
<a href="#">lorem</a>
<a href="#">ipsum</a>
<a href="#">lorem</a>
<a href="#">ipsum</a>
<a href="#">lorem</a>
<a href="#">ipsum</a>
</div>
<div class="panel">
<a href="#">lorem</a>
<a href="#">ipsum</a>
<a href="#">lorem</a>
<a href="#">ipsum</a>
</div>
<div class="panel">
<a href="#">lorem</a>
<a href="#">ipsum</a>
</div>
<div class="panel" style="height: 3000px;"></div>
Upvotes: 1