Scrollspy widget (Working)

This wiget is useful for having a top bar which will track several anchors while the user scrolls down

by jmeile

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/simple-scrollspy/2.4.2/simple-scrollspy.min.js"></script>
Some content here
<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
      <div class="menu" id="main-menu">
        <a class="menu-item active" href="#hero">Hero</a>
        <a class="menu-item" href="#section-1">Section 1</a>
        <a class="menu-item" href="#section-2">Section 2</a>
        <a class="menu-item" href="#section-3">Section 3</a>
        Non existent
        <a class="menu-item" href="#section-4">Section 4</a>
        <a class="menu-item" href="#section-5">Section 5</a>
        <a class="menu-item" href="#section-6">Section_6</a>
      </div>
      
  <section class="section scrollspy" id="hero"><h3>Hero</h3>
On the other hand, we denounce with righteous indignation and dislike men who are so beguiled and demoralized by the charms of pleasure of the moment, so blinded by desire, that they cannot foresee the pain and trouble that are bound to ensue; and equal blame belongs to those who fail in their duty through weakness of will, which is the same as saying through shrinking from toil and pain. These cases are perfectly simple and easy to distinguish. In a free hour, when our power of choice is untrammelled and when nothing prevents our being able to do what we like best, every pleasure is to be welcomed and every pain avoided. But in certain circumstances and owing to the claims of duty or the obligations of business it will frequently occur that pleasures have to be repudiated and annoyances accepted. The wise man therefore always holds in these matters to this principle of selection: he rejects pleasures to secure other greater pleasures, or else he endures pains to avoid worse pains.
  </section>
  <section class="section scrollspy" id="section-1"><h3>Section 1</h3>
  <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
  <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
 ...

CSS

.menu { 
  /* Avoid top and bottom margins for the menu; otherwise, you will get
   * unexpected results when navigating to the different sections; mostly, the
   * vertical space won't match what you are expecting. The problem is that
   * these margins will overlap with the section margins. At best work with
   * paddings or give margins to the content before the navigation bar and to
   * the sections
   */
  margin-top: 0px;
  margin-bottom: 0px;
  
  /* Top and bottom paddings are ok and they will be substracted */
  padding-top: 5px;
  padding-bottom: 5px;
  
  border-color: #d3d3d3 !important;
  border-bottom: 1px solid;
  color: #d3d3d3 !important;
  background-color: #fff;
}

/* The sticky class is added to the navbar with JS when it reaches its scroll position */
.sticky {
  position: fixed;
  top: 0;
  width: 100%;
  background-color: #fff !important;
}

/* Add some top padding to the page content to prevent sudden quick movement (as the navigation bar gets a new position at the top of the page (position:fixed and top:0) */
.sticky+.content {
  padding-top: 60px;
}

.menu-item {
  margin-left: 5px;
  margin-right: 5px;
  padding-bottom: 4px;
  font-size: 1rem;
}

.menu-item,
.menu-item:hover,
.menu-item.active {
  color: #000 !important;
  text-decoration: none;
}

.menu-item.active {
  border-color: #000 !important;
  border-bottom: 3px solid;
}

.menu-item:hover {
  border-color: #d3d3d3 !important;
  border-bottom: 3px solid;
}

.menu-item:first-child {
  margin-left: 0px;
}

.menu-item:last-child {
  margin-right: 0px;
}

.section {
  padding-top: 1.5rem;
  margin-top: 1.5rem;
}

.section h3 {
  /* Make sure that the first element comming in the section doesn't
   * have any margin or padding at the top; otherwise, the results won't
   * look as expected because they will overlap the section paddings and margins
   */
  padding-top: 0;
  margin-top: 0;
  margin-bottom: 1.25rem;
  font-size: 1.5rem;
  font-weight: normal;
}

JavaScript

/* This code was taken from:
   * simple-scrollspy by kimyvgy
   * https://github.com/kimyvgy/simple-scrollspy
   */
  window.onload = function() {
    scrollSpy('#main-menu', {
      sectionClass: '.scrollspy',
      menuActiveTarget: '.menu-item',
      offset: 54,
      // scrollContainer: null,
      // smooth scroll
      smoothScroll: true,
      smoothScrollBehavior: function(element) {
        if (stickyHeight == 0) {
          console.log("sticky");
        } else {
          console.log("not sticky");
        }
      
        var paddingTop = parseFloat(window.getComputedStyle(element, null).getPropertyValue('padding-top'));
        var marginTop = parseFloat(window.getComputedStyle(element, null).getPropertyValue('margin-top'));
        window.scrollTo({
        	left: element.offsetLeft,
          // Here you need to substract the computed top padding and
          //margin of the section. Additionally, when the menu is sticked,
          //then you also have to substract the height of the menu
          //The offsetFix is to hide the last parts of the letters after the
          //base line
          top: element.offsetTop - paddingTop - marginTop - stickyHeight - stickyVerticalOffset + offsetFix,
          behavior: "smooth"
        });
        //This won't work for sticky elements
				/*
				element.scrollIntoView({
          behavior: 'smooth'
        })
        */
      },
      onActive: (el) => {
        //console.log('run "onActive"...', el)
      }
    })
  }

  /* This code was taken from:
   * How TO - Sticky/Affix Navbar
   * https://www.w3schools.com/howto/howto_js_navbar_sticky.asp
   */
  // When the user scrolls the page, execute stickMenu
  window.onscroll = function() {
    stickMenu()
  };

  // Get the navbar
  var navbar = document.getElementById("main-menu");

  // Get the offset position of the navbar
  var stickyOffsetTop = navbar.offsetTop;
  
  //Get the vertical position of the navigation bar
  var stickyHeight =...