2

I've been trying to figure this out for hours. I currently have a fixed nav for my anchor website. I would like the menu link background color to change when scrolling through each section. Like this: https://codepen.io/dbilanoski/pen/LabpzG . When I scroll through each section I only see the hover background color not the active state color. If you have any tips or advice, please advise.

Thank you!

var navLink = $(".nav-link"),
  topMenuHeight = navLink.outerHeight() + 15,
  //All list items
  menuItems = navLink.find("a"),
  //Anchors corresponding to menu items
  scrollItems = menuItems.map(function() {
    var item = $($(this).attr("href"));
    if (item.length) {
      return item;
    }
  });
// Bind click handler to menu items
// so we can get a fancy scroll animation
menuItems.click(function(e) {
  var href = $(this).attr("href")
  offsetTop = href === "#" ? 0 : $(href).offset().top - topMenuHeight + 1;
  $('html, body').stop().animate({
    scrollTop: offsetTop
  }, 300);
  e.preventDefault();
});
// Bind to scroll
$(window).scroll(function() {
  // Get container scroll position
  var fromTop = $(this).scrollTop() + topMenuHeight;

  // Get id of current scroll item
  var cur = scrollItems.map(function() {
    if ($(this).offset().top < fromTop)
      return this;
  });
  // Get the id of the current element
  cur = cur[cur.length - 1];
  var id = cur && cur.length ? cur[0].id : "";

  if (navLink !== id) {
    navLink = id;
    // Set/remove active class
    menuItems
      .parent().removeClass("active")
      .end().filter("[href='#" + id + "']").parent().addClass("active");
  }
});
a {
  color: inherit;
  text-decoration: none;
}

a:hover {
  color: #fa448c;
  text-decoration: underline;
}

a:active {
  background-color: #fa448c;
  color: #fff;
}

li {
  list-style-type: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="menu">
  <ul class="nav-list">
    <li class="nav-item">
      <a href="#home" class="nav-link">Home</a>
    </li>
    <li class="nav-item">
      <a href="#products" class="nav-link">Products</a>
    </li>
    <li class="nav-item">
      <a href="#featured" class="nav-link">Featured</a>
    </li>
    <li class="nav-item">
      <a href="#best-sellers" class="nav-link">Best Sellers</a>
    </li>
    <li class="nav-item">
      <a href="#contact" class="nav-link">Contact</a>
    </li>
  </ul>
</div>

1 Answers1

2

The trick of the codepen you've sent is that all sections have the same height. However, there's a more flexible way of doing that. Using this solution, you check for each section whether it's shown on the screen or not, and if it is, highlight its button in the navlist.

Ilya Maximov
  • 149
  • 1
  • 8
  • Thank you! I read through the post & it seems like Intersection Observer API should be used. But there's a lot of different answers, so I'm not too sure if Intersection Observer API is what I should use. –  Dec 11 '20 at 10:37