Is it possible to dynamically select an element id and change its colour with JQuery when scrolling?

Viewed 63

As the list item scrolls up it changes colour and back again as it reaches the top or bottom of the window. Exactly as hoped. However is there a more elegant solution that uses just one function? I've been trying $(this) to select the target element when scrolling but I've not yet managed to crack it.

$(document).ready(function() {
    $(window).scroll(function() {
        var middleview = $(window).height()/2; //find middle of window
        var m = $( "#moving" );
      var mposition = m.position(); //get position of first element
        var d = $( "#dynamic" );
        var dposition = d.position(); //get position of second element
        var a = $( "#active" );
        var aposition = a.position(); //get position of third element
        var s = $( "#spirited" );
        var sposition = s.position(); //get position of fourth element
        var e = $( "#energetic" );
        var eposition = e.position(); //get position of fifth element
        var f = $( "#finish" );
        var fposition = f.position(); //get position of final element

      if ($(document).scrollTop() > mposition.top - middleview &&  $(document).scrollTop() < dposition.top - middleview) { //set colour change area
        $("#moving").removeClass("defaultcolor"); // remove default class
        $("#moving").addClass('color-' + $("#moving").data('color')); // change colour
      } else {
        $("#moving").removeClass('color-' + $("#moving").data('color')); // remove colour change
        $("#moving").addClass("defaultcolor"); // add default class
      }

     if ($(document).scrollTop() > dposition.top - middleview &&  $(document).scrollTop() < aposition.top - middleview) { //top then bottom
        $("#dynamic").removeClass("defaultcolor");
        $("#dynamic").addClass('color-' + $("#dynamic").data('color'));
      } else {
        $("#dynamic").removeClass('color-' + $("#dynamic").data('color'));
        $("#dynamic").addClass("defaultcolor");
      }

     if ($(document).scrollTop() > aposition.top - middleview &&  $(document).scrollTop() < sposition.top - middleview) { //top then bottom
        $("#active").removeClass("defaultcolor");
        $("#active").addClass('color-' + $("#active").data('color'));
      } else {
        $("#active").removeClass('color-' + $("#active").data('color'));
        $("#active").addClass("defaultcolor");
      }

     if ($(document).scrollTop() > sposition.top - middleview &&  $(document).scrollTop() < eposition.top - middleview) { //top then bottom
        $("#spirited").removeClass("defaultcolor");
        $("#spirited").addClass('color-' + $("#spirited").data('color'));
      } else {
        $("#spirited").removeClass('color-' + $("#spirited").data('color'));
        $("#spirited").addClass("defaultcolor");
      }

     if ($(document).scrollTop() > eposition.top - middleview &&  $(document).scrollTop() < fposition.top - middleview) { //top then bottom
        $("#energetic").removeClass("defaultcolor");
        $("#energetic").addClass('color-' + $("#energetic").data('color'));
      } else {
        $("#energetic").removeClass('color-' + $("#energetic").data('color'));
        $("#energetic").addClass("defaultcolor");
      }
    });
  });
body {
    height:1550px;
    background-color: #f1f2eb;
    font-size: 3em;
    font-style: italic;
    text-align: center;
  }

  div {
    height:50%;
    }

  ul {
    list-style-type: none;
    line-height: 300%;
  }

 .defaultcolor {
    color:white;
    transition: 1s;
 }

  .color-green {
    color: #095256;
    transition: 1s;
  }

  .color-orange {
    color: #e46e1e;
    transition: 1s;
  }

  .color-black {
    color: #C79F1C;
    transition: 1s;
  }
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
<div></div>
<ul>
 <li id="moving" class="defaultcolor" data-color="green">MOVING</li>
 <li id="dynamic" class="defaultcolor" data-color="orange">DYNAMIC</li>
 <li id="active" class="defaultcolor" data-color="black">ACTIVE</li>
 <li id="spirited" class="defaultcolor" data-color="orange">SPIRITED</li>
 <li id="energetic" class="defaultcolor" data-color="green">ENERGETIC</li>
</ul>
<z id="finish"></z>
<div></div>
</body>
</html>

1 Answers

It is possible! See the below snippet. Instead of defining ids just loop through all the elements (I gave them a class of .colortext) and perform your action. If the next() element doesn't exist, I set it to the finish element that you have.

$(document).ready(function() {
  $(window).scroll(function() {
    var middleview = $(window).height() / 2; //find middle of window
    $('.colortext').each((_, text) => {
      var textElem = $(text);
      var top = $(document).scrollTop();
      var color = textElem.data('color');
      var next = textElem.next();
      if (next.length === 0) {
        next = $('#finish');
      }

      if (top > textElem.position().top - middleview && top < next.position().top - middleview) { // set colour change area
        textElem.removeClass("defaultcolor"); // remove default class
        textElem.addClass('color-' + color); // change colour
      } else {
        textElem.removeClass('color-' + color); // remove colour change
        textElem.addClass("defaultcolor"); // add default class
      }
    })
  });
});
body {
  height: 1550px;
  background-color: #f1f2eb;
  font-size: 3em;
  font-style: italic;
  text-align: center;
}

div {
  height: 50%;
}

ul {
  list-style-type: none;
  line-height: 300%;
}

.defaultcolor {
  color: white;
  transition: 1s;
}

.color-green {
  color: #095256;
  transition: 1s;
}

.color-orange {
  color: #e46e1e;
  transition: 1s;
}

.color-black {
  color: #C79F1C;
  transition: 1s;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div></div>
<ul>
  <li id="moving" class="colortext defaultcolor" data-color="green">MOVING</li>
  <li id="dynamic" class="colortext defaultcolor" data-color="orange">DYNAMIC</li>
  <li id="active" class="colortext defaultcolor" data-color="black">ACTIVE</li>
  <li id="spirited" class="colortext defaultcolor" data-color="orange">SPIRITED</li>
  <li id="energetic" class="colortext defaultcolor" data-color="green">ENERGETIC</li>
</ul>
<z id="finish"></z>
<div></div>

Related