RonTheOld RonTheOld - 1 year ago 156
CSS Question

Navigation have an active class working

Hi guys so i got my navbar to work on a one page navgation. However i want it so that when the user scrolls down the page manual the nav classes change to which one should be active, so when they go past the section the nav bar will highlight the active section.

I can get it to work when they click on it, but not manually scroll

Fiddle

HTML:

<nav class="navbar navbar-default" data-spy="affix" data-offset-top="10">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li><a href="#a">a</a></li>
<li><a href="#b">b</a></li>
<li><a href="#c">c</a></li>
<li><a href="#d">d</a></li>
</ul>
</div>
<!--/.nav-collapse -->
</div>
</nav>

<div id="a"></div>
<div id="b"></div>
<div id="c"></div>
<div id="d"></div>


CSS:

affix {
top: 0;
width: 100%
}


.affix + .section {
margin-top: 68px;
}

.navbar {
margin-bottom: 0px;
left: 0;
top: 0;
width: 100%;
list-style: none;
height: 70px;
z-index: 1
}

.navbar-nav {
float: none;
margin: 0;
text-align: center
}

.navbar-nav>li {
float: none;
display: inline-block
}

.navbar-nav>li>a {
line-height: 38px
}

.navbar-nav>li>a.active {
background-color: #E7E7E7
}

.navbar-default .navbar-nav>li>a:hover, .navbar-default .navbar-nav>li>a:focus {
color: #333333;
background-color: #E7E7E7
}

.navbar-toggle {
background-color: #000000;
background-image: none;
border-radius: 4px;
float: right;
margin-bottom: 8px;
margin-right: 15px;
margin-top: 18px;
padding: 9px 10px;
position: relative
}

.navbar-inverse .navbar-toggle .icon-bar {
background-color: #2DCC70
}

.navbar-default .navbar-toggle:hover, .navbar-default .navbar-toggle:focus {
background-color: #000000
}

.navbar-inverse .navbar-collapse, .navbar-inverse .navbar-form {
border-color: transparent
}

#a{
height: 700px;
background-color: Red;
}

#b{
height: 700px;
background-color: blue;
}

#c{
height: 700px;
background-color: yellow;
}

#d{
height: 700px;
background-color: black;
}


JS:

$(function() {
$('ul.nav a').bind('click',function(event){
event.preventDefault();

var $anchor = $(this);

//Update active link
$('ul.nav a').removeClass('active');
$anchor.addClass('active');

//Animate scroll position
$('html, body').stop().animate({
scrollTop: $($anchor.attr('href')).offset().top
}, 1000);
});
});

Answer Source

You could do this with scrollspy. The Javascript library called Waypoints is another possibility.

Here's an example of how you could use Waypoints:

function makeNavActive($elem) {
  if (typeof $elem !== "jQuery") {
    $elem = $($elem);
  }
  $('ul.nav a').removeClass('active');
  $elem.addClass('active');
}

function waypointHandler() {
  var elementID = this.element.id;
  makeNavActive("[href='#" + elementID + "']");
}

var waypointA = new Waypoint({
  element: document.getElementById('a'),
  handler: waypointHandler,
  offset: 38
});

var waypointB = new Waypoint({
  element: document.getElementById('b'),
  handler: waypointHandler,
  offset: 38
});

var waypointC = new Waypoint({
  element: document.getElementById('c'),
  handler: waypointHandler,
  offset: 38
});

var waypointAD = new Waypoint({
  element: document.getElementById('d'),
  handler: waypointHandler,
  offset: 38
});

Fiddle

I'm sure you could create a better way of setting up the waypoints but this will serve as an example.

Kinda for fun I also created a way of doing it in vanilla JS. So here's a nice lightweight vanilla implementation, although less flexible than using waypoints:

function makeNavActive($elem) {
      if (typeof $elem !== "jQuery") {
        $elem = $($elem);
      }
      $('ul.nav a').removeClass('active');
      $elem.addClass('active');
}

function handleScroll(){
        var scrollLevel = Math.floor(window.pageYOffset / 700);
        console.log(scrollLevel);
    if(scrollLevel === 0) {makeNavActive("[href='#a']")}
    else if(scrollLevel === 1) {makeNavActive("[href='#b']")}
    else if(scrollLevel === 2) {makeNavActive("[href='#c']")}
    else if(scrollLevel === 3) {makeNavActive("[href='#d']")}
}
window.onscroll=handleScroll

Fiddle

Hope that helps! Best of luck with your project.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download