Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

138
Vistas
Change nav-link style depending on which div is in viewport in React

I have a SPA with a long height page, where one section represents one page. Actual code:

const ScrollWrapper = () => {
  return (
  <div className={styles.ScrollWrapper + ` ` + 'snap-container'}>
    <div className={styles['navigation-fix-wrapper']}>
      <ScrollNavigation/>
    </div>
    <Home/>
    <Projects/>
    <Media/>
    <Concerts/>
    <Contacts/>
  </div>
)};

A have a navigation component at the top. It's a bunch of anchors with list items inside it, every anchor links to a sections like with scrolling effect, no page changes. On click styling of an clicked link changes to active.

Goal: implement IntersectionObserver to all of my sections (from Home to Contacts) and depending on which component is in viewport the active link in ScrollNavigation component will be changed (if I scroll from Home to Concerts, the Concerts link will be active)

I have absolute zero ideas how can I do it, but I'm pretty sure that there are some ways.

I think of something like (pseudocode):

 const [activeLink, setActiveLink] = useState('home')
 //some code here
 if (IntersectionObserver.state === 'home' {
   setActiveLink('home')
 } else if (IntersectionObserver.state === 'concerts' {
   setActiveLink('concerts')
 }
 //some code here
 return (
  <div className={styles.ScrollWrapper + ` ` + 'snap-container'}> 
    <ScrollNavigation active={activeLink} />
  //some code here
  </div>
 )

UPDATE:

Added this code to ScrollWrapper, as kritiz suggested. IntersectionObserver fires console.log only if parent component is in if condition, but not the children. What I'm doing wrong?

  useEffect(() => {
    var observer = new IntersectionObserver(onIntersection, {
      root: null,   // default is the viewport
      threshold: .5 // percentage of taregt's visible area. Triggers "onIntersection"
    })
    
    // callback is called on intersection change
    function onIntersection(entries, opts){
      entries.forEach(entry => {
        if (entry.target.id === 'projects') {
          console.log('projects')
        } 
      }  
  
      )
    }
    observer.observe( document.querySelector('.snap-container') )

  }, [])

Changed target to currentTarget, error occures:

Cannot read properties of undefined (reading id) 
about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

As kritiz suggested, I used a scroll event listener on window and it actually worked. It still sounds like memory leaks, and I will continue to try implementing the IntersectionObserver, but it works as I needed.

Code:

  useEffect(() => {
    
    window.addEventListener('scroll', function() {
      
      const observable = {
        home: document.querySelector('.home'),
        projects: document.querySelector('.projects'),
        media: document.querySelector('.media')
  
      }
      const pos = {
        home: observable.home.getBoundingClientRect(),
        projects: observable.projects.getBoundingClientRect(),
        media: observable.media.getBoundingClientRect()
      }
      

      if (pos.home.top < window.innerHeight && pos.home.bottom >= 0) {
        setActiveLink('home')
      } else if (pos.projects.top < window.innerHeight && pos.projects.bottom >= 0) {
        setActiveLink('projects')
      } else if (pos.media.top < window.innerHeight && pos.media.bottom >= 0) {
        setActiveLink('media')
      }
    })

    return () => {
      
    }
  }, [])

UPDATE:

Second approach is to use react-scroll library, which works like a charm and does everything I need.

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda