Как добавить функцию (jQuery) чтобы активный пунк меню изменялся при скролле?

сразу к проблеме! Есть меню(справа вверху). Это меню плавно переходит к якорям.

<!DOCTYPE html>
<html lang="ru">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Demo</title>

    <!-- Bootstrap -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
    
    <style>
      #block1{
        height: 400px;
        width:100%;
        display: block;
        background-color: #ffa2a2;
      }
      #block2{
        height: 400px;
        width:100%;
        display: block;
        background-color: #b4ffb4;
      }
      #block3{
       height: 400px;
       width:100%;
       display: block;
       background-color: #6f6fff;
      }
      #block4{
       height: 400px;
       width:100%;
       display: block;
       margin-bottom:500px;
       background-color: #ccc;
      }
      .nav-pills.nav-stacked{
       position: fixed;
       right:0px;
       top:0px;
      }
    </style>
  </head>
  <body>
      
    <div class="container-fluid">
      <div class="row">

        <div class="col-lg-8 col-md-8 col-sm-8 col-xs-12">
          <section id="block1">
            block1
          </section> 
          <section id="block2">
            block2
          </section> 
          <section id="block3">
            block3
          </section> 
          <section id="block4">
            block4
          </section>
        </div>

        <div class="col-lg-4 col-md-4 col-sm-4 col-xs-12 right-fixed-menu">
          <ul class="nav nav-pills nav-stacked">
            <li class="active"><a href="javascript://0" onclick="slowScroll('#block1')">Главная</a></li>
            <li><a href="javascript://0" onclick="slowScroll('#block2')">Профиль</a></li>
            <li><a href="javascript://0" onclick="slowScroll('#block3')">Сообщение</a></li>
            <li><a href="javascript://0" onclick="slowScroll('#block4')">Контакты</a></li>
          </ul>
        </div>

      </div>
    </div>

    <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
    <!-- Include all compiled plugins (below), or include individual files as needed -->
    
    <script>
      $(document).on('click' , '.nav-stacked li', function(){
        $(this).addClass('active').siblings().removeClass('active');
      })
   
      function slowScroll(id) {
        var offset = 0;
        $('html, body').animate({
            scrollTop: $(id).offset().top - offset
        }, 500);
        return false;
      }
    </script>
  </body>
</html>

Как мне добавить функцию Scroll_block в код который я предоставил выше, как здесь https://liblessons.ru/makeup/fixed-active-menu/ Чтобы при скролле активный пункт изменялся. Или альтернативный способ, только без Bootstrap. Годится и чистый js Заранее спасибо!


Ответы (2 шт):

Автор решения: grvctr

Держи, может не слишком красиво и костыльно, но можешь это попробовать

      $(document).scroll(() => {
    const menuItems = $('.nav-stacked li');
    const currentIndex = Math.floor(($(document).scrollTop()/400));
    const currentItem = menuItems[currentIndex];
    $(currentItem).addClass('active').siblings().removeClass('active');
  })

<!DOCTYPE html>
<html lang="ru">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Demo</title>

    <!-- Bootstrap -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
    
    <style>
      #block1{
        height: 400px;
        width:100%;
        display: block;
        background-color: #ffa2a2;
      }
      #block2{
        height: 400px;
        width:100%;
        display: block;
        background-color: #b4ffb4;
      }
      #block3{
       height: 400px;
       width:100%;
       display: block;
       background-color: #6f6fff;
      }
      #block4{
       height: 400px;
       width:100%;
       display: block;
       margin-bottom:500px;
       background-color: #ccc;
      }
      .nav-pills.nav-stacked{
       position: fixed;
       right:0px;
       top:0px;
      }
    </style>
  </head>
  <body>
      
    <div class="container-fluid">
      <div class="row">

        <div class="col-lg-8 col-md-8 col-sm-8 col-xs-12">
          <section id="block1">
            block1
          </section> 
          <section id="block2">
            block2
          </section> 
          <section id="block3">
            block3
          </section> 
          <section id="block4">
            block4
          </section>
        </div>

        <div class="col-lg-4 col-md-4 col-sm-4 col-xs-12 right-fixed-menu">
          <ul class="nav nav-pills nav-stacked">
            <li class="active"><a href="javascript://0" onclick="slowScroll('#block1')">Главная</a></li>
            <li><a href="javascript://0" onclick="slowScroll('#block2')">Профиль</a></li>
            <li><a href="javascript://0" onclick="slowScroll('#block3')">Сообщение</a></li>
            <li><a href="javascript://0" onclick="slowScroll('#block4')">Контакты</a></li>
          </ul>
        </div>

      </div>
    </div>

    <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
    <!-- Include all compiled plugins (below), or include individual files as needed -->
    
    <script>
      $(document).on('click' , '.nav-stacked li', function(){
        $(this).addClass('active').siblings().removeClass('active');
      })

      $(document).scroll(() => {
        const menuItems = $('.nav-stacked li');
        const currentIndex = Math.floor(($(document).scrollTop()/400));
        const currentItem = menuItems[currentIndex];
        $(currentItem).addClass('active').siblings().removeClass('active');
      })
   
      function slowScroll(id) {
        var offset = 0;
        $('html, body').animate({
            scrollTop: $(id).offset().top - offset
        }, 500);
        return false;
      }
    </script>
  </body>
</html>

→ Ссылка
Автор решения: grvctr

Вот еще один вариант с разными высотами

<!DOCTYPE html>
<html lang="ru">

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Demo</title>

    <!-- Bootstrap -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">

    <style>
        #block1 {
            height: 400px;
            width: 100%;
            display: block;
            background-color: #ffa2a2;
        }

        #block2 {
            height: 450px;
            width: 100%;
            display: block;
            background-color: #b4ffb4;
        }

        #block3 {
            height: 400px;
            width: 100%;
            display: block;
            background-color: #6f6fff;
        }

        #block4 {
            height: 600px;
            width: 100%;
            display: block;
            margin-bottom: 500px;
            background-color: #ccc;
        }

        .nav-pills.nav-stacked {
            position: fixed;
            right: 0px;
            top: 0px;
        }
    </style>
</head>

<body>

    <div class="container-fluid">
        <div class="row">

            <div class="col-lg-8 col-md-8 col-sm-8 col-xs-12">
                <section id="block1">
                    block1
                </section>
                <section id="block2">
                    block2
                </section>
                <section id="block3">
                    block3
                </section>
                <section id="block4">
                    block4
                </section>
            </div>

            <div class="col-lg-4 col-md-4 col-sm-4 col-xs-12 right-fixed-menu">
                <ul class="nav nav-pills nav-stacked">
                    <li class="active"><a href="javascript://0" onclick="slowScroll('#block1')">Главная</a></li>
                    <li><a href="javascript://0" onclick="slowScroll('#block2')">Профиль</a></li>
                    <li><a href="javascript://0" onclick="slowScroll('#block3')">Сообщение</a></li>
                    <li><a href="javascript://0" onclick="slowScroll('#block4')">Контакты</a></li>
                </ul>
            </div>

        </div>
    </div>

    <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"
        integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
    <!-- Include all compiled plugins (below), or include individual files as needed -->

    <script>
        $(document).on('click' , '.nav-stacked li', function(){
        $(this).addClass('active').siblings().removeClass('active');
      })
 
      $(document).scroll(() => {
        const menuItems = $('.nav-stacked li');
        const blockItems = $('section');
        let blockItemsPositions = []; // позиция блока
        let currentIndex = 0; // текущий индекс меню
        let currentPosition = $(document).scrollTop(); // текущая позиция
        for(let i = 0; i < blockItems.length; i++) { 
          blockItemsPositions.push($(blockItems[i]).offset().top);
        }
        let temp = blockItemsPositions.filter(item => item <= currentPosition); // фильтруем до нужных нам блоков, подходящих по позиции
        
        let currentBlock = temp[temp.length-1]; // берем последний

        currentIndex = blockItemsPositions.indexOf(currentBlock);

        const currentItem = menuItems[currentIndex];
        $(currentItem).addClass('active').siblings().removeClass('active');
      })
   
      function slowScroll(id) {
        var offset = 0;
        $('html, body').animate({
            scrollTop: $(id).offset().top - offset
        }, 500);
        return false;
      }
    </script>
</body>

</html>

→ Ссылка