Bootstrap4 плавный скролл

204
10 декабря 2021, 19:20

html :

 <style>
  .checkpoint {
    margin-top: 800px;
    width: 100px;
    height: 100px;
    background: black;
  }
</style>
  <header>
    <nav class='navbar navbar-expand-lg navbar-dark fixed-top scrolling-navbar'>
      <div class='container'>
        <a class="navbar-brand black-text">VegasAccademy</a>
        <button class="navbar-toggler" type='button' data-toggle="collapse" data-target="#basicExampleNav" aria-controls="basicExampleNav" aria-expanded="false" aria-label="Toggle Navigation">
          <span class="navbar-toggler-icon"></span>
        </button>
        <div class='collapse navbar-collapse' id='basicExampleNav'>
          <ul class="navbar-nav mr-auto smooth-scroll">
            <li class='nav-item'>
              <a  class='nav-link waves-effect waves-light' href="#intro">Home</a>
            </li>
            <li class='nav-item'>
              <a  class='nav-link waves-effect waves-light' href="#about">About</a>
            </li>
            <li class='nav-item'>
              <a  class='nav-link waves-effect waves-light' href="#purpose">Purpose</a>
            </li>
            <li class='nav-item'>
              <a  class='nav-link waves-effect waves-light' href="#teachers">Teachers</a>
            </li>
            <li class='nav-item'>
              <a  class='nav-link waves-effect waves-light' href="#map">Map</a>
            </li>
          </ul>
          <ul class='navbar-nav nav-flex-icons'>
          <li class='nav-item'>
            <a href="" class='nav-link waves-effect waves-light'>
              <i class="fa fa-facebook"></i>
            </a>
          </li>
           <li class='nav-item'>
            <a href="" class='nav-link waves-effect waves-light'>
              <i class="fa fa-instagram"></i>
            </a>
          </li>
           <li class='nav-item'>
            <a href="" class='nav-link waves-effect waves-light'>
              <i class="fa fa-twitter"></i>
            </a>
          </li>
          </ul>
        </div>
      </div>
    </nav>
    <div id='intro' class='view'>
      <div class='mask rgba-black-strong'>
        <div class='container-fluid d-flex align-items-center justify-content-center h-100'>
          <div class='row d-flex justify-content-center text-center'>
            <div class='col-md-10'>
              <h2 class='display-4 font-weight-bold white-text pt-5 mb-2'>
                Studying in EU
              </h2>
              <hr class='hr-light'>
              <h4 class='white-text my-4'>Knowledge makes one laugh, but wealth makes one dance.</h4>
              <button type='button' class='btn btn-outline-white waves-effect waves-light'>Read More <i class='fa fa-book'></i></button>
            </div>
          </div>
        </div>
      </div>
    </div>
  </header>
  <div class='checkpoint' id='about'></div> 
  <div class='checkpoint' id='purpose'></div>
  <script src="js/jquery.min.js"></script>
  <script src="js/popper.min.js"></script>
  <script src="js/bootstrap.min.js"></script>
  <script src="js/mdb.min.js"></script>

По неизвестной мне причине не работает плавный скрол.

Answer 1

Для плавного скрола используйте либо Jquery:

var $page = $('html, body');
$('a[href*="#"]').click(function() {
    $page.animate({
        scrollTop: $($.attr(this, 'href')).offset().top
    }, 400);
    return false;
});

Либо Javascript:

// собираем все якоря; устанавливаем время анимации и количество кадров 
const anchors = [].slice.call(document.querySelectorAll('a[href*="#"]')), 
      animationTime = 300, 
      framesCount = 20; 
 
anchors.forEach(function(item) { 
  // каждому якорю присваиваем обработчик события 
  item.addEventListener('click', function(e) { 
    // убираем стандартное поведение 
    e.preventDefault(); 
     
    // для каждого якоря берем соответствующий ему элемент и определяем его координату Y 
    let coordY = document.querySelector(item.getAttribute('href')).getBoundingClientRect().top + window.pageYOffset; 
     
    // запускаем интервал, в котором 
    let scroller = setInterval(function() { 
      // считаем на сколько скроллить за 1 такт 
      let scrollBy = coordY / framesCount; 
       
      // если к-во пикселей для скролла за 1 такт больше расстояния до элемента 
      // и дно страницы не достигнуто 
      if(scrollBy > window.pageYOffset - coordY && window.innerHeight + window.pageYOffset < document.body.offsetHeight) { 
        // то скроллим на к-во пикселей, которое соответствует одному такту 
        window.scrollBy(0, scrollBy); 
      } else { 
        // иначе добираемся до элемента и выходим из интервала 
        window.scrollTo(0, coordY); 
        clearInterval(scroller); 
      } 
    // время интервала равняется частному от времени анимации и к-ва кадров 
    }, animationTime / framesCount); 
  }); 
});
h2 { 
  margin-bottom: 100vh; 
}
<ul> 
  <li><a href="#head1">head 1</a> 
  <li><a href="#head2">head 2</a> 
  <li><a href="#head3">head 3</a> 
  <li><a href="#head4">head 4</a> 
</ul> 
 
<h2 id="head1">heading 1</h2> 
<h2 id="head2">heading 2</h2> 
<h2 id="head3">heading 3</h2> 
<h2 id="head4">heading 4</h2>

Answer 2

К ответу выше. В js'е не обязательно считать время анимации и кол-во кадров. Есть уже нативные способы анимации скролла.

Javascript:

const headerH = document.querySelector('.header').getBoundingClientRect().height; // Если  header имеет position: fixed; то берём его высоту, чтобы скролл не перекрывал элемент на конец анимации. Если header не фиксированный, то можно его не использовать. (1)
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
  anchor.addEventListener('click', function (e) {
    e.preventDefault();
    let currentHref    = this.getAttribute('href'),
        currentAnchor  = document.getElementById(currentHref.substring(1)),
        currentAnchorT = currentAnchor.getBoundingClientRect().top;
    window.scrollTo({
      top: currentAnchorT - headerH + window.scrollY, // headerH не обязателен (1)
      behavior: 'smooth'
    });
  });
});
READ ALSO
Как реализовать анимацию css через JS

Как реализовать анимацию css через JS

Необходимо, что бы при клике на ссылку вырисовывалась линия, попытался менять ширину линии с помощью JS, предварительно установив элементу...

170
Как получить значения семплов в audioWorklet?

Как получить значения семплов в audioWorklet?

У меня есть буфер входящих аудио фреймов в wasm модуль

175
Использование WebSokets [закрыт]

Использование WebSokets [закрыт]

Хотите улучшить этот вопрос? Переформулируйте вопрос так, чтобы он был сосредоточен только на одной проблеме

147
возможно ли исправить день. недели?

возможно ли исправить день. недели?

Есть несколько дат, часть из которых по григорианскому календарю, а часть по юлианскому, дело в том что в датах по юлианскому календарю дни...

65