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

215
Visualizações
Adding class dynamically based on which element is being scrolled past

I have a nav which contains letters and sections which are associated to letters in the nav.

When a user scrolls to a section, I want to addClass active to that letter. For example:

  • User scrolls to section with the id of a, the anchor with the data-letter with a will be active.

Currently, on scroll, all my letters in the nav become active and this is because it's always thinking it's on section A.

Demo:

$(function() {
  $(window).scroll(function() {
    
    // step 1: get id of section
    var visible_section = $('section:visible'), id = visible_section.attr('id');
    console.log(id);

    // step 2: add class where id and data-letter match
  $("nav a").removeClass("active");
  $("nav a[data-letter='"+id+"']").addClass("active");
    
  });
});
.nav {
  background: grey;
  padding: 30px 15px;
  position: fixed;
  top: 0;
  width: 100%;
}

.nav a {
  padding: 0 15px;
  text-decoration: none;
}

.nav a:hover {
  background: black;
  color: white;
}

.nav a.active {
  background: black;
  color: white;
}

.sections {
  margin-top: 100px;
}

section {
  padding: 200px 0;
  color: red;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 50px;
}

section:nth-child(odd) {
  background-color: black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/3e7Jo4EaG7TubfWGUrMQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>


<main>

  <nav class="nav">
    <a href="#a" data-letter="a">A</a>
    <a href="#b" data-letter="b">B</a>
    <a href="#c" data-letter="c">C</a>
    <a href="#d" data-letter="d">D</a>
  </nav>

  <div class="sections">
    <section id="a">A</section>
    <section id="b">B</section>
    <section id="c">C</section>
    <section id="d">D</section>
  </div>

</main>

about 4 years ago · Juan Pablo Isaza
3 Respostas
Responde à pergunta

0

FYI: https://stackoverflow.com/a/5354536/4571790

function isVisible(elm) {
  var rect = elm.getBoundingClientRect();
  var viewHeight = Math.max(document.documentElement.clientHeight, window.innerHeight);
  return !(rect.bottom < 0 || rect.top - viewHeight >= 0);
}

$(function() {
  $(window).scroll(function() {
    
    // step 1: get id of section
    var visible_section = $('section:visible'), id="";
    
    // this code will find which section is the first visible
    $(".sections").find("section").each((i,a)=>id==""?(isVisible(a)?id=$(a).attr("id"):id):id);
    $("#result").html(id +" is visible now");
    //console.log(id);

    // step 2: add class where id and data-letter match
  $("nav a").removeClass("active");
  $("nav a[data-letter='"+id+"']").addClass("active");
    
  });
});
.nav {
  background: grey;
  padding: 30px 15px;
  position: fixed;
  top: 0;
  width: 100%;
}

.nav a {
  padding: 0 15px;
  text-decoration: none;
}

.nav a:hover {
  background: black;
  color: white;
}

.nav a.active {
  background: black;
  color: white;
}

.sections {
  margin-top: 100px;
}

section {
  padding: 200px 0;
  color: red;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 50px;
}

section:nth-child(odd) {
  background-color: black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/3e7Jo4EaG7TubfWGUrMQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>


<main>

  <nav class="nav">
    <a href="#a" data-letter="a">A</a>
    <a href="#b" data-letter="b">B</a>
    <a href="#c" data-letter="c">C</a>
    <a href="#d" data-letter="d">D</a>
    <span id="result"></span>
  </nav>

  <div class="sections">
    <section id="a">A</section>
    <section id="b">B</section>
    <section id="c">C</section>
    <section id="d">D</section>
  </div>

</main>

about 4 years ago · Juan Pablo Isaza Relatório

0

You should differentiate the nav tabs by setting their data-letter as you described to a, b, c and d:

<nav class="nav">
    <a href="#a" data-letter="a">A</a>
    <a href="#b" data-letter="b">B</a>
    <a href="#c" data-letter="c">C</a>
    <a href="#d" data-letter="d">D</a>
</nav>

All your nav become active not because it always thinks it's on a, but because all data-letter are set to a.

about 4 years ago · Juan Pablo Isaza Relatório

0

You can change ratio from 0.1 to 1:

            $(function () {
                let ratio = 0.6; // From 0.1 to 1
                $(window).scroll(function () {
                    let sections = $('.sections section');
                    let scrollTop = $(window).scrollTop();
                    let screen_height = $(window).height();
                    $.each(sections, function () {
                        let top = $(this).offset().top;
                        let calc = (top - scrollTop) / screen_height;
                        if (calc >= (ratio * -1) && calc <= ratio) {
                            let id = $(this).attr('id');
                            $("nav a").removeClass("active");
                            $("nav a[data-letter='" + id + "']").addClass("active");
                            //console.log(`${id} is Active`);
                        }
                    });
                });
            });
.nav {
            background: grey;
            padding: 30px 15px;
            position: fixed;
            top: 0;
            width: 100%;
        }

        .nav a {
            padding: 0 15px;
            text-decoration: none;
        }

        .nav a:hover {
            background: black;
            color: white;
        }

        .nav a.active {
            background: black;
            color: white;
        }

        .sections {
            margin-top: 100px;
        }

        section {
            padding: 200px 0;
            color: red;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 50px;
        }

        section:nth-child(odd) {
            background-color: black;
        }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<main>

        <nav class="nav">
            <a href="#a" data-letter="a">A</a>
            <a href="#b" data-letter="b">B</a>
            <a href="#c" data-letter="c">C</a>
            <a href="#d" data-letter="d">D</a>
        </nav>

        <div class="sections">
            <section id="a">A</section>
            <section id="b">B</section>
            <section id="c">C</section>
            <section id="d">D</section>
        </div>
    </main>

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