#StackBounty: #javascript #html #jquery #css Jquery custom scrollspy active nav item

Bounty: 50

I’m trying to make a custom scrollspy for a website.

When scroll down I want first of all make the nav fixed/sticky, that works perfectly. When scroll down further I try to make the current nav item active, by adding a class active.

But whatever I try I just can’t get that class active added to the nav item when we are at that specific section. I don’t get any errors whatsoever so I rerally don’t know anymore what I do wrong. I just can’t see it.

Is this perhaps the wrong approach or can someone see why it won’t get active?

$(function() {
  var $anchor = $('.product-menu');
  if ($anchor.length) {
    var $menuItems = $anchor.find('a'),
      $scrollItems = $menuItems.map(function() {
        var item = $($(this).attr("href"));
        if (item.length) {
          return item;
        }
      }),
      initPosition = $anchor.offset().top;
    $(window).scroll(function() {
      var htop = $('#header').outerHeight(true) - 1;
      if (initPosition != $anchor.offset().top && !$anchor.hasClass('sticky')) {
        initPosition = $anchor.offset().top;
      }
      if ($(window).scrollTop() >= initPosition - htop) {
        $anchor.addClass("sticky").css({
          top: htop
        });
      } else {
        $anchor.removeClass("sticky");
      }
      if ($anchor.length && $(window).width() > 768) {
        var cur = $scrollItems.map(function() {
          if ($(window).scrollTop() >= $(this).offset().top - $anchor.outerHeight() - $('#header').outerHeight()) return this;
        });
        cur = cur[cur.length - 1];
        var id = cur && cur.length ? cur[0].id : "";
        $menuItems.removeClass("active").end().filter("[href='#" + id + "']").addClass("active");
      }
    });
  }
});
#header {
  background: indianred;
  color: #fff;
  height: 60px;
  position: sticky;
  top: 0;
  z-index: 98;
  transition: all ease-in-out .25s;
  box-shadow: 0 5px 10px rgba(0,0,0,.05);
}

.product-menu {
  margin: 45px 0;
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  height:60px;
  line-height:60px;
  box-shadow: 0 5px 10px rgba(0,0,0,.05);
}

.product-menu.sticky {
  position: sticky;
  background: #fff;
  z-index: 9;
  width: 100%;
}

.list-inline {
  padding-left: 0;
  list-style: none;
  display: flex;
  flex-direction: row;
  align-items: center;
  margin: 0;
}

.list-inline li {
  margin: 0 5px;
}

.product-block {
  height: 300px;
  background: #eee;
  border: 1px solid #000;
}
<html>

<head>
  https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js
</head>

<body>
  <header id="header">
    <div class="header flex flex-align-center flex-between container">
      <div class="logo">
        <img src="" alt="Logo" width="" height="64" />
      </div>
    </div>
    <nav id="menu" class="nav list-inline">
      <ul class="list-inline container">
        <li><a href="#" class="goSmoothly">Main nav item</a></li>
        <li><a href="#" class="goSmoothly">Main nav item</a></li>
        <li><a href="#" class="goSmoothly">Main nav item</a></li>
        <li><a href="#" class="goSmoothly">Main nav item</a></li>
        <li><a href="#" class="goSmoothly">Main nav item</a></li>
      </ul>
    </nav>
  </header>
  <div class="some-container">
    <nav class="product-menu">
      <ul class="list-inline container">
        <li><a href="#description" class="goSmoothly">Product information</a></li>
        <li><a href="#specifications" class="goSmoothly">Specifications</a></li>
        <li><a href="#bundles" class="goSmoothly">Product bundles</a></li>
        <li><a href="#reviews" class="goSmoothly">Reviews</a></li>
        <li><a href="#related" class="goSmoothly">Related products</a></li>
      </ul>
    </nav>
    <div class="desc">
      <div id="description" class="product-block">description</div>
      <div id="specifications" class="product-block">specifications</div>
    </div>
    <div class="info">
      <div id="bundles" class="product-block">bundles</div>
      <div id="reviews" class="product-block">reviews</div>
    </div>
    <div id="related" class="product-block">related</div>
  </div>
</body>

</html>


Get this bounty!!!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.