<section class="section">Some section 1</section>
<section class="section">Some section 2</section>
<section class="section">Some section 3</section>
<section class="section">Some section 4</section>
body {
  margin: 0;
  font-family: Tahoma;
  font-size: 18px;
}

.section {
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
}

.section:nth-child(odd) {
  background: #333;
  color: #fff;
}
var pagePositon = 0,
  sectionsSeclector = "section",
  $scrollItems = $(sectionsSeclector),
  offsetTolorence = 30,
  pageMaxPosition = $scrollItems.length - 1;

//Map the sections:
$scrollItems.each(function (index, ele) {
  $(ele).attr("debog", index).data("pos", index);
});

// Bind to scroll
$(window).bind("scroll", upPos);

//Move on Scroll
window.addEventListener("wheel", function (event) {
  if (event.deltaY < 0) {
    if (pagePositon - 1 >= 0) {
      pagePositon--;
      $("html, body")
        .stop()
        .animate(
          {
            scrollTop: $scrollItems.eq(pagePositon).offset().top
          },
          500
        );
      return false;
    }
  } else if (event.deltaY > 0) {
    if (pagePositon + 1 <= pageMaxPosition) {
      pagePositon++;
      $("html, body")
        .stop()
        .animate(
          {
            scrollTop: $scrollItems.eq(pagePositon).offset().top
          },
          500
        );
    }
  }
});

//Update position func:
function upPos() {
  var fromTop = $(this).scrollTop();
  var $cur = null;
  $scrollItems.each(function (index, ele) {
    if ($(ele).offset().top < fromTop + offsetTolorence) $cur = $(ele);
  });
  if ($cur != null && pagePositon != $cur.data("pos")) {
    pagePositon = $cur.data("pos");
  }
}

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js