Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

141
Visualizações
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 Respostas
Responde à pergunta

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda