is there a way to change fixed element style when enter any section element on scroll

Solution 1:

The easiest thing to do would be to have the fixed button have a background color that looks good on all sections. That way you can just style it and leave it alone.

If you have to have the color change at different sections, there are a few ways of doing that, none are easy, and only a few would have good performance.

The best way of doing this that I can think of would be:

  • Have the background of the fixed button be the default color.
  • Add a class modifier so that when you add one class it changes the style to the new color. Example: .button becomes .button.red
  • On each section that has to change the background of the button, add a custom data-attribute Example: <section change-button-bg="red">
  • Then on load
    1. Set up a .querySelectorAll(*[change-button-bg]) so that you can run a check on each of the sections.
    2. Add a global variable called currentTarget
    3. Set up an Intersection Observer on all the sections.
  • Have the callback function for .isIntersecting do a few things.
    1. Update the currentTaget variable
    2. Update the color of the button
    3. Add a scroll listener
  • In the scroll listener watch the bounds.bottom of currentTarget to see which color it should be.
  • Then in the Intersection Observer, if it's no longer intersecting, remove the scroll listener to prevent memory leaks.

Here is a working example.

window.addEventListener('load', (event) => {
  const changeBG = document.querySelectorAll('*[change-button-bg]');
  let currentTarget = null;
  
  const Observer = new IntersectionObserver((entries, Observer) => {
    for (const entry of entries) {
      if (entry.isIntersecting) {
        currentTarget = entry.target;
        addColor(true);
        window.addEventListener('scroll', watchTarget);
      } else {
        addColor(false);
        window.removeEventListener('scroll', watchTarget)
      }
    }
  }, {threshold: 0.15});

  for (const element of changeBG) {
    Observer.observe(element);
  }
  
  function watchTarget() {
    const bounds = currentTarget.getBoundingClientRect();
    
    if (bounds.bottom < window.innerHeight - 80) {
        addColor(false);
    } else {
      addColor(true);
    }
  }
  
  function addColor(add) {
    const btn = document.getElementById('button');
    if (add) {
      btn.classList.add('red');
    } else {
      btn.classList.remove('red');
    }    
  }
  
});
body {
  margin: 0;
}
section {
  width: 100vw;
  height: 100vh;
  background: red;
}

section:nth-child(even) {
  background: blue;
}

button {
  position:fixed;
  right: 50px;
  bottom: 50px;
  padding: 15px 25px;
  border: none;
  color: white;
  background-color: blue;
  cursor: pointer;
}

button.red {
  background-color: red;
}
<html>
  <body>
    <section></section>
    <section change-button-bg="red"></section>
    <section></section>
    <section change-button-bg="red"></section>
    <section></section>
    <button id="button">Top</button>
  </body>
</html>

Solution 2:

this is the solution I was looking for I did it using Intersection Observer

   document.addEventListener('DOMContentLoaded',()=>{
    let options = {
      root:null,
      rootMargin:"-570px 0px -100px 0px",
      threshold:0.05

    };

  let Observer= new IntersectionObserver(changColor,options);
    document.querySelectorAll("section").forEach(section => {
      Observer.observe(section);
    });
  });


function changColor(elements) {
elements.forEach(el => {
   if (el.isIntersecting) {
    let elbg=el.target.dataset.bg;
 
    if (elbg=="blue") { //if section data-bg== blue
     
      // change svg button style
         document.getElementById("chatting_path_7").style.fill = "#fff";
         document.getElementById("to_top_Ellipse_4").style.stroke = "#fff";
    } else {
        document.getElementById("chatting_path_7").style.fill = "#034ea2";
        document.getElementById("to_top_Ellipse_4").style.stroke = "#034ea2";
    }
  }
})

}