Home > Net >  How to make this code work with multiple sticky navbars on the same page?
How to make this code work with multiple sticky navbars on the same page?

Time:11-29

I use this JS solution to make the navigation bar sticky when we scroll down the page. The problem is that I have multiple tabs on the page and each tab has the same navigation bar. Thus, this solution makes only the first navigation bar sticky. Is there a way to make this work for all of them?

In this code, I find objects by class name (it's intentional, I need to use search by class name, not by ID), but it finds the first object with such class name and therefore ignores the rest. How can I change this code so that it works with many objects with the same class names? I copy this navbar several times in different tabs of the page so class names are the same.

// When the user scrolls the page, execute myFunction
window.onscroll = function() {myFunction()};

// Get the navbar
var navbararray = document.getElementsByClassName("sticky-navbar");
var navbar = navbararray[0];

//Get the inner container
var innercontainerarray = document.getElementsByClassName("future-page-wrapper");
var innercontainer = innercontainerarray[0];
  
// Get the offset position of the navbar
var sticky = navbar.offsetTop;

// Add the sticky class to the navbar when you reach its scroll position. Remove "sticky" when you leave the scroll position
function myFunction() {
  if (window.pageYOffset >= sticky   250) {
    navbar.classList.add("sticky");
    innercontainer.classList.add("page-wrapper");
  } else {
    navbar.classList.remove("sticky");
    innercontainer.classList.remove("page-wrapper")
  }
}
/* Style the navbar */
.sticky-navbar {
  overflow: hidden;
  background-color: #333;
}

/* Navbar links */
.sticky-navbar a {
  float: left;
  display: block;
  color: #f2f2f2;
  text-align: center;
  padding: 14px;
  text-decoration: none;
}

/* Page content */
.content {
  padding: 16px;
}

/* The sticky class is added to the navbar with JS when it reaches its scroll position */
.sticky {
  position: fixed;
  top: 0;
  width: 100%;
  left: 0;
}

/* 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;
}

.page-wrapper {
  margin: 0px 250px;
}
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<div >
<div id="navbar" >
  <div >
  <a href="#home">Home</a>
  <a href="#news">News</a>
  <a href="#contact">Contact</a>
  </div>
</div>
</div>
<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>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
Test
<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>

CodePudding user response:

It looks like the primary issue is that you're explicitly grabbing the first of the navbars and applying the sticky logic. Instead, you'll want to iterate over all the navbars and apply your logic within that loop like so:

// Get the navbars
var navbararray = document.querySelectorAll(".sticky-navbar");

// rather than only operating on a single navbar, pass the whole array
window.onscroll = function () { myFunction(navbararray) };

// Add the sticky class to the navbar when you reach its scroll position. Remove "sticky" when you leave the scroll position
function myFunction(navbararray) {
  navbararray.forEach(navbar => {

  //Get the inner container
  var innercontainerarray = document.getElementsByClassName("future-page-wrapper");
  var innercontainer = innercontainerarray[0];

  // Get the offset position of the navbar
  var sticky = navbar.offsetTop;

  if (window.pageYOffset >= sticky   250) {
    navbar.classList.add("sticky");
    innercontainer.classList.add("page-wrapper");
  } else {
    navbar.classList.remove("sticky");
    innercontainer.classList.remove("page-wrapper");
  }

  });
}

Edit: A little extra info - rather than using getElementsByClassName I used document.querySelectorAll('.sticky-navbar'). This gives you a non-live array of all objects with the aforementioned class (documentation here)

  • Related