简体   繁体   中英

Javascript - How to make a section 'active' when scrolled to

I'm very new to JavaScript so apologies if I'm lacking clarity in any of my description.

I've built a small website that has a java-script generated menu and I'm just wanting to add functionality to highlight a section (and make 'active') in the menu when scrolled to. I've put together the following, which isn't throwing any errors in the console, so I'm unsure what I've missed:

const sectionHead = document.querySelectorAll('h2');

const sections = document.querySelectorAll('section');
const nav = document.querySelector('nav');

// build the nav
function navMenu(){
  for(let section of sectionHead){
      let listItem = document.createElement("li");
      listItem.innerHTML = section.textContent;
      nav.appendChild(listItem);
      listItem.classList.add('menu__link');
      listItem.addEventListener("click", ()=>{
        section.scrollIntoView({behavior: "smooth"});
      });
  };
}
navMenu();

const nav_items = document.querySelectorAll('.menu__link')

window.addEventListener("scroll", () => {
  let current = "";
  sections.forEach((section) => {
    const sectionTop = section.offsetTop;
    const sectionHeight = section.clientHeight;
    if (pageYOffset >= sectionTop - sectionHeight / 3) {
      current = section.getAttribute("id");
    }
  });
//set section as active
  nav_items.forEach((li) => {
    li.classList.remove("your-active-class");
    section.classList.remove("your-active-class");
    if (section.classList.contains(current)) {
      section.classList.add("your-active-class");
      //console.log (li.classList);
    }
  });
});

The 'your-active-class' class has some custom CSS setup so it will just change visibility in the menu.

Any help is really appreciated

This is how you would observe whether a DOM Element is within view, and apply/remove a classname to it. If you look at your inspector, you'll see the 'active' class being added/removed when they enter and exit view.

 window.addEventListener("load", function() { //Query objects on document load const sections = document.querySelectorAll("section") console.log(`We have ${sections.length} sections`) // Create options for Observer: const options = { rootMargin: '100px 0px', threshold: [0.25, 0, 0.25, 0] } // Create instance of IO: let observer = new IntersectionObserver(entries => { entries.forEach(entry => { if (entry.intersectionRatio > 0) { entry.target.classList.add('active') } else { entry.target.classList.remove('active') } }) }, options) // Iterate over each queried el, and add observer: sections.forEach(section => { observer.observe(section) }) })
 section { background-color: red; display: flex; justify-content: center; align-items: center; height: 100vh; margin: 6rem auto; transition: all 300ms ease-in-out; }.active { background-color: rgba(0,255,0,0.3); transition: all 300ms ease-in-out; }
 <section><div>This is the first section</div></section> <section><div>This is the second</div></section> <section><div>This is the third</div></section>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM