Кнопка «Вниз» на чистом JavaScript

Сложность

HTML 20%
CSS 80%
JavaScript 60%

Вступление

Делаем на нативном JavaScript анимированную кнопку, при клике на которую, происходит скролл на один «экран» вниз.

HTML часть

<div class="wrapper">
  <button type="button" class="scroll_down" id="scroll_down"></button>
</div>

Создадим обертку, внутри которой и будет наша кнопка.
Class будем использовать в CSS, а id в JavaScript.

CSS часть

.wrapper {
  background: -webkit-linear-gradient(right, #c56f82, #497ccb);
  background: linear-gradient(270deg, #c56f82, #497ccb);
  height: 100vh;
  text-align: center;
  margin-left: auto;
  margin-right: auto;
  position: relative;
}

/* begin Scroll Down Button */
button.scroll_down {
  position: absolute;
  margin-left: auto;
  margin-right: auto;
  left: 0;
  right: 0;
  height: 50px;
  width: 30px;
  bottom: 60px;
  background-color: transparent;
  border: 2px solid white;
  border-radius: 20px;
  cursor: pointer;
  outline: none;
}

button.scroll_down:before {
  position: absolute;
  top: 10px;
  left: 50%;
  content: '';
  width: 6px;
  height: 6px;
  margin-left: -3px;
  background-color: #fff;
  border-radius: 100%;
  -webkit-animation: scroll_down_btn-animation 2s infinite;
  animation: scroll_down_btn-animation 2s infinite;
  box-sizing: border-box;
}

@keyframes scroll_down_btn-animation {
  0% {
    transform: translate(0, 0);
    opacity: 0;
  }
  40% {
    opacity: 1;
  }
  80% {
    transform: translate(0, 20px);
    opacity: 0;
  }
  100% {
    opacity: 0;
  }
}

@-webkit-keyframes scroll_down_btn-animation {
  0% {
    -webkit-transform: translate(0, 0);
    transform: translate(0, 0);
    opacity: 0;
  }
  40% {
    opacity: 1;
  }
  80% {
    -webkit-transform: translate(0, 20px);
    transform: translate(0, 20px);
    opacity: 0;
  }
  100% {
    opacity: 0;
  }
}

/* end Scroll Down Button */

Обертке зададим position: relative; Кнопке position: absolute; И позиционируем кнопку в нужное место.

Но кнопка у нас не простая, а с анимацией, поэтому напишем эту самую анимацию, через псевдоэлемент  :before. Для того чтобы «точка» двигалась, создадим правило @keyframes, назовем его scroll_down_btn-animation, цикл анимации будет повторяться бесконечно.

JavaScript часть

/* begin Scroll Down Button */
(function() {
  'use strict';

  var btnScrollDown = document.querySelector('#scroll_down');

  function scrollDown() {
    var windowCoords = document.documentElement.clientHeight;
    (function scroll() {
      if (window.pageYOffset < windowCoords) {
        window.scrollBy(0, 10);
        setTimeout(scroll, 0);
      }
      if (window.pageYOffset > windowCoords) {
        window.scrollTo(0, windowCoords);
      }
    })();
  }

  btnScrollDown.addEventListener('click', scrollDown);
})();
/* end Scroll Down Button */

Выбираем нашу кнопку и записываем ее в переменную, далее на неё записываем обработчик клика.

Создаем переменную windowCoords и в нее записываем данные о высоте видимой области окна; подробнее о clientHeight  можно почитать здесь learn.javascript.ru.

Далее для плавности скролла делаем анимацию, для этого создаем рекурсию. Функция проверяет текущую вертикальную прокрутку страницы и сравнивает ее с нашим значением в переменной windowCoords, если значение прокрутки страницы меньше значения в windowCoords, то прокручивает страницу вниз на 10px(за счет функции scrollBy() ), далее функция вызывает сама себя и проделывает все тоже самое; а за счет не мгновенного вызова самой себя, а с небольшой задержкой(через функцию setTimeout()), получается эффект плавности прокрутки. По другому говоря, функция вызывает сама себя постоянно, пока условие(window.pageYOffset < windowCoords) истинно и при каждом вызове прокручивает страницу вниз на 10px, как только условие становится ложно, функция прекращает свою работу.

Но здесь у нас есть еще одно условие (window.pageYOffset > windowCoords), оно здесь затем, что нам нужна точность прокрутки(в 1px) , а наша рекурсия, как мы выяснили, при каждом вызове прокручивает страницу на 10px, следовательно, прокрутка может быть больше необходимой(в пределах 9px), а для этого и нужно второе условие. Оно проверяет не перекрутили ли мы страницу вниз, и если да, то возвращает ее в нужное положение(с помощью метода scrollTo()).

Заключение

Кнопку с анимацией, при клике на которую происходит прокрутка на один «экран» вниз, сделать оказалось несложно.

Прокомментировать можно здесь, или на stackoverflow.

Живое демо можно посмотреть на codepen. Там специально добавлен нижний блок с верхним красным бордером, для демонстрации точности прокрутки.