javascriptoffset

Toggle class of fixed header when hovering specific divs in Javascript


I'm building a site with a fixed header positioned at the top of the window. I'm trying to toggle a class to switch the color of the header when scrolling hover specific divs with the class .is-dark

While scrolling, the header is hovering a div with the class .is-dark, the color of header is white. If not, the color is black.

Here is the JS code, unfortunately doesn't seem to work:

const header = document.querySelector(".js-header");
const sections = document.querySelectorAll(".has-dark-theme");

sections.forEach((section) => {
    
window.addEventListener('scroll', () => {
    
    const fixed_position = header.offsetTop;
    const fixed_height = header.offsetHeight;

    const toCross_position = section.offsetTop;
    const toCross_height = section.offsetHeight;
    
    if (fixed_position + fixed_height < toCross_position) {
        header.classList.remove('is-white');
    } else if (fixed_position > toCross_position + toCross_height) {
        header.classList.remove('is-white');
    } else {
            header.classList.add('is-white');
    }

})
    
})
.site-header {
  position: fixed;
  width: 100%;
  height: 3em;
  top: 0;
  left: 0;
  color: black;
}

.site-header.is-white {
  color: white;
}

.section {
  width: 100%;
  height: 100vh;
  background-color: white;
}

.section.is-dark {
  background-color: black;
}
<header class="site-header"></header>

<div class="section is-dark"></div>
<div class="section"></div>
<div class="section is-dark"></div>
<div class="section is-dark"></div>
<div class="section"></div>
<div class="section"></div>


Solution

  • You are not checking if the header is overlapping with any of these sections while scrolling.

    Refer the attached code below for checking overlaping :

    window.addEventListener('scroll', () => {
        const header = document.querySelector(".site-header");
        const sections = document.querySelectorAll(".is-dark");
    
        let headerIsWhite = false;
    
        sections.forEach((section) => {
            const fixed_position = window.scrollY;
            const fixed_height = header.offsetHeight;
    
            const toCross_position = section.offsetTop;
            const toCross_height = section.offsetHeight;
    
            
            if (fixed_position < toCross_position + toCross_height && fixed_position + fixed_height > toCross_position) { // Check if the header is within the bounds of the section
                headerIsWhite = true;
            }
        });
    
        if (headerIsWhite) {
            header.classList.add('is-white');
        } else {
            header.classList.remove('is-white');
        }
    });
    .site-header {
      position: fixed;
      width: 100%;
      height: 3em;
      top: 0;
      left: 0;
      color: black;
    }
    
    .site-header.is-white {
      color: white;
    }
    
    .section {
      width: 100%;
      height: 100vh;
      background-color: white;
    }
    
    .section.is-dark {
      background-color: black;
    }
    <header class="site-header"></header>
    
    <div class="section is-dark"></div>
    <div class="section"></div>
    <div class="section is-dark"></div>
    <div class="section is-dark"></div>
    <div class="section"></div>
    <div class="section"></div>