<body>
  <div class="wrap">
    <div class="sidebar">
      <ul class="sidebar_list">
        <li><a href="#about">ABOUT</a></li>
        <li><a href="#blog">BLOG</a></li>
        <li><a href="#news">NEWS</a></li>
        <li><a href="#contact">CONTACT</a></li>
      </ul>
    </div>
    <div class="main">
      <div id="about">ABOUT</div>
      <div id="blog">BLOG</div>
      <div id="news">NEWS</div>
      <div id="contact">CONTACT</div>
    </div>
  </div>
  <footer>
    
  </footer>
</body>
body{
  margin: 0;
}

ul {
  list-style: none;
}

a {
  text-decoration: none;
  cursor: pointer;
  color: #555;
}         

#about{
  width: 100%;
  height: 800px;
  background-color: #94b7e6;
}
#blog{
  width: 100%;
  height: 800px;
  background-color: #bdbdbd;
}
#news{
  width: 100%;
  height: 800px;
  background-color: #f0d7a1;
}
#contact{
  width: 100%;
  height: 800px;
  background-color: #ff9898;
}

.wrap{
  display: flex;
}
.sidebar{
  background-color: beige;
  width: 25%;
  position: relative;
}
.sidebar_list{
  padding: 0;
}
.sidebar li{
  background-color: #ffffff;
  margin: 10px 0;
}
.main{
  width: 75%;
}

.action {
  border-left: 5px solid #000000;
}

.is_fixed {
  position: fixed;
  top: 0;
  width: 25%;
}

.is_absolute {
  position: absolute;
  bottom: 0;
  width: 100%;
}
footer{
  width: 100%;
  height: 600px;
  background-color: #daffbc;
}
$(function() {
  var $fixElement = $('.sidebar_list'); // 追従する要素
  var $sidebar = $('.sidebar'); 
  var $sidebarHeight = $sidebar.offset().top + $sidebar.height();
  console.log($sidebar.height());
  console.log($sidebar.offset().top);
  var baseFixPoint = $fixElement.offset().top; // 追従する要素の初期位置
  var fixClass = 'is_fixed'; // 追従時に付与するclass
  var absoClass = 'is_absolute'; // 追従時に付与するclass

  // 要素が追従する処理
  function fixFunction() {
      var windowScrolltop = $(window).scrollTop();
      console.log(windowScrolltop);
      // スクロールが初期位置を通過しているとき
      if(windowScrolltop >= $sidebarHeight - $fixElement.height()){
        $fixElement.addClass(absoClass);
        $fixElement.removeClass(fixClass);
      } else if(windowScrolltop >= baseFixPoint) {
          $fixElement.addClass(fixClass);
          $fixElement.removeClass(absoClass);
      } else {
          $fixElement.removeClass(fixClass);
          $fixElement.removeClass(absoClass);
      }
  }

  $(window).on('load scroll', function() {
      fixFunction();
  });
});


$(function() {
  // ナビゲーションのリンクを指定
 var navLink = $('ul.sidebar_list li a');

  // 各コンテンツのページ上部からの開始位置と終了位置を配列に格納しておく
 var contentsArr = new Array();
for (var i = 0; i < navLink.length; i++) {
     // コンテンツのIDを取得
    var targetContents = navLink.eq(i).attr('href');
    // ページ内リンクでないナビゲーションが含まれている場合は除外する
    if(targetContents.charAt(0) == '#') {
       // ページ上部からコンテンツの開始位置までの距離を取得
          var targetContentsTop = $(targetContents).offset().top;
       // ページ上部からコンテンツの終了位置までの距離を取得
          var targetContentsBottom = targetContentsTop + $(targetContents).outerHeight(true) - 1;
       // 配列に格納
          contentsArr[i] = [targetContentsTop, targetContentsBottom]
    }
 };

// 現在地をチェックする
 function currentCheck() {
     // 現在のスクロール位置を取得
      var windowScrolltop = $(window).scrollTop();
      for (var i = 0; i < contentsArr.length; i++) {
         // 現在のスクロール位置が、配列に格納した開始位置と終了位置の間にあるものを調べる
        if(contentsArr[i][0] <= windowScrolltop && contentsArr[i][1] >= windowScrolltop) {
              // 開始位置と終了位置の間にある場合、ナビゲーションにclass="current"をつける
             navLink.removeClass('action');
             navLink.eq(i).addClass('action');
              i == contentsArr.length;
          }
     };
}

 // ページ読み込み時とスクロール時に、現在地をチェックする
$(window).on('load scroll', function() {
    currentCheck();
});

// ナビゲーションをクリックした時のスムーズスクロール
  navLink.click(function() {
    $('html,body').animate({
        scrollTop: $($(this).attr('href')).offset().top
     }, 300);
      return false;
 })
});
Run Pen

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