Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding and removing class, applying styles on scroll

Problem

I'm having an issue adding and removing classes, applying styles on scroll.

Specifically, when I scroll down the page:

  • The class of is-red is still on the first .dot__outer group when you scroll down the page when it should be removed, there should be one group highlighted with the is-red class
  • There seems to be an issue with my if-statement, as the colors are remaining their default colors and not changing on scroll

Expected behavior

Scrolling:

  • On scroll, remove the class is-red on all divs with a class of dot__outer
  • Add a class of is-red to the next dot__outer in the series after the user has scrolled past a specific panel. i.e. If a user is on panel two, the second group should be highlighted red

Dot colors:

  • On black backgrounds, the dots and their borders should be white
  • On white backgrounds, the dots and their borders should be black
  • In both instances, any dot__outer with a class of is-red should be red

scripts.js

$(function() {

  function updateProgress() {
    let dot = $(".dot");

    let dotsBottom = $(".dots").offset().top + $(".dots").outerHeight();
    let panelHeaderBottom =$(".panel-1").offset().top + $(".panel-1").outerHeight();
    let panelRelatedTop = $(".panel-8").offset().top;

    // If the `dot__outer` has a class of `is-active` the dot should also be red. By default, the dot and border should be white.
    if (dot.parent().hasClass("is-red")) {
      $(this).css("background", "red");
    } else {

      // If the position of the dots is less than the bottom of the header or greater than the top of the related section, the dots are white. Otherwise, the dots are black
      if (dotsBottom < panelHeaderBottom || dotsBottom > panelRelatedTop) {
        $(this).css("background", "#000");

      } else {
        $(this).css("background", "#fff");
      }
    }

    $(".panel").each(function(index) {
      let currentPosition = $(window).scrollTop();
      let panelTop = $(this).offset().top;
      let panelBottom = $(this).offset().top + $(this).outerHeight();

      if ((currentPosition > panelTop) && (currentPosition < panelBottom)) {        
        $(".dot__outer").removeClass("is-red");
        $(".dot__outer").eq(index).addClass("is-red");
      } else {
        $(".dot__outer").eq(0).addClass("is-red");
      }
    });
  }

  $(window).scroll(function() {
    updateProgress();
  });
});

index.html

<div class="panels">
  <div class="panel panel-1">Panel #1</div>
  <div class="panel panel-2">Panel #2</div>
  <div class="panel panel-3">Panel #3</div>
  <div class="panel panel-4">Panel #4</div>
  <div class="panel panel-5">Panel #5</div>
  <div class="panel panel-6">Panel #6</div>
  <div class="panel panel-7">Panel #7</div>
  <div class="panel panel-8">Panel #8</div>
</div>

<div class="dots">

  <div class="dot__outer is-red">
    <div class="dot"></div>
  </div>

  <div class="dot__outer">
    <div class="dot"></div>
  </div>

  <div class="dot__outer">
    <div class="dot"></div>
  </div>

  <div class="dot__outer">
    <div class="dot"></div>
  </div>

  <div class="dot__outer">
    <div class="dot"></div>
  </div>

  <div class="dot__outer">
    <div class="dot"></div>
  </div>

  <div class="dot__outer">
    <div class="dot"></div>
  </div>

  <div class="dot__outer">
    <div class="dot"></div>
  </div>
</div>

Codepen

https://codepen.io/yacoubian/pen/PBOVKw?editors=1010

UPDATE

Scrolling issue fixed, codpen updated.

like image 311
Mary Yacoubian Avatar asked Jul 30 '18 18:07

Mary Yacoubian


1 Answers

This is another approach that you might take:

function updateProgress() {
    let dotsBottom = $(".dots").offset().top + $(".dots").outerHeight();
    let dotBorder = $(".dot__outer");

    let headerBottom = $(".panel-1").offset().top + $(".panel-1").outerHeight();
    let relatedTop = $(".panel-8").offset().top;

    $(".panel").each(function(index) {
        let currentPosition = $(window).scrollTop();
        let panelTop = $(this).offset().top;
        let panelBottom = $(this).offset().top + $(this).outerHeight();

        if (currentPosition > panelTop && currentPosition < panelBottom) {
            dotBorder.removeClass("is-red");
            dotBorder.eq(index).addClass("is-red").children().css("background", "red");

            if (dotsBottom < headerBottom || dotsBottom > relatedTop) {
                dotBorder.not(".is-red").children().css("background", "#fff");
            } else {
                dotBorder.not(".is-active").children().css("background", "#000");
            }
        }
    });
}
like image 156
Andrew Nguyen Avatar answered Oct 14 '22 06:10

Andrew Nguyen