JSFiddle - React, Tailwind, and code Playground

HTML

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-mousewheel/3.1.13/jquery.mousewheel.min.js"></script>
<body>
  <div class="as-marker"></div>
  <div style="background-color:red;" class="autoscroll">
    <p style="line-height:3;color:white;">
    Ipsum Lorem<br><br>Ipsum Lorem<br><br>Ipsum Lorem<br><br>Ipsum Lorem<br><br>Ipsum Lorem
    </p>
  </div>
  <div class="as-marker"></div>
  <div style="background-color:blue;" class="autoscroll">
    <p style="line-height:3;color:white;">
    Ipsum Lorem<br><br>Ipsum Lorem<br><br>Ipsum Lorem<br><br>Ipsum Lorem<br><br>Ipsum Lorem<br><br>Ipsum Lorem<br><br>Ipsum Lorem<br><br>Ipsum Lorem<br><br>Ipsum Lorem<br><br>
    </p>
  </div>
  <div class="as-marker"></div>
  <div style="background-color:green;" class="autoscroll">
    <p style="line-height:3;color:white;">
    Ipsum Lorem<br><br>Ipsum Lorem<br><br>Ipsum Lorem<br><br>Ipsum Lorem<br><br>Ipsum Lorem<br><br>Ipsum Lorem<br><br>Ipsum Lorem
    </p>
  </div>
  <div class="as-marker"></div>
  <div style="background-color:brown;" class="autoscroll">
    <p style="line-height:3;color:white;">
    Ipsum Lorem<br><br>Ipsum Lorem<br><br>Ipsum Lorem<br><br>Ipsum Lorem<br><br>Ipsum Lorem<br><br>
    </p>
  </div>
</body>

CSS

.autoscroll{
  min-height:100%;
}
html, body, p{
  margin:0;
  padding:0;
}

JavaScript

function isElementInViewport (el) {
    //this function is taken from
		//http://stackoverflow.com/questions/123999/how-to-tell-if-a-dom-element-is-visible-in-the-current-viewport/7557433#7557433
    
    //special bonus for those using jQuery
    if (typeof jQuery === "function" && el instanceof jQuery) {
        el = el[0];
    }

    var rect = el.getBoundingClientRect();

    return (
        rect.top >= 0 &&
        rect.left >= 0 &&
        rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && /*or $(window).height() */
        rect.right <= (window.innerWidth || document.documentElement.clientWidth) /*or $(window).width() */
    );
}

$(function() {
  var $scroller = $(document), isScrolling, scTimeout, lastScrollTop = 0;

	console.clear();

  // the scroll event listener
  $scroller.on('scroll', function(event) {
  	clearTimeout(scTimeout);
    
    var scrollTop = $scroller.scrollTop();
    var scrollDir = (scrollTop > lastScrollTop) ? 'down' : 'up';
    
    console.log('scrolled', scrollDir);
    
    if (scrollTop != lastScrollTop) {
      lastScrollTop = scrollTop;

      if (!isScrolling) {
        scTimeout = setTimeout(function() {
            isScrolling || scrollHandler(scrollDir);
        }, 50);    
      }
    }
  });

  // the scroll handler
  function scrollHandler(dir) {
    console.log('scrollHandler', dir);
  	clearTimeout(scTimeout);
    
    var $markers = $('.as-marker');
  	var toElement = null;
    
    switch (dir) {
    	case 'down':
        $markers.each(function() {
          if (isElementInViewport(this)) {
            // take the last visible marker in viewport
            toElement = this;
          }            
        });
      	break;
      case 'up':
        $markers.each(function(index) {          	
          if (isElementInViewport(this)) {
            // take the first visible marker in viewport
            // and scroll to the previous marker
            toElement = $markers.get(Math.max(0,...