skip to Main Content

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>

2

Answers


  1. 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>
    Login or Signup to reply.
  2. First look at the classes, there you need to specify not only the color but also the background color.
    Then you don’t need to select elements every time you scroll. That’s not cool. In addition, you need to check the original position of the element during the page load, it may load against a white block or a black block. Take some of the code out of the loop and some of it into a function and you’ll have a good optimization at once

        const header = document.querySelector('.site-header');
        const sections = document.querySelectorAll('.section');
            check_position(sections,header);
        window.addEventListener('scroll', () => {
            check_position(sections,header);
        });
    
    function check_position(sections,header){
       sections.forEach(section => {
                  const rect = section.getBoundingClientRect();
                if (rect.top <= 0 && rect.bottom >= header.clientHeight) {
                    if (section.classList.contains('is-dark')) {
                       header.classList.add('is-white');
                    } else {
                         header.classList.remove('is-white');  
                    } 
                }
        });
    }
    .site-header {
        position: fixed;
        width: 100%;
        height: 50px;
        top: 0;
        left: 0;
        background: black;
    }
    
    .site-header.is-white {
        background: white;
    }
    
    .section {
        width: 100%;
        height: 100vh;
        background: white;
    }
    
    .section.is-dark {
        background: 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>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search