Плавный скролл до элемента

Реализуем следующее: после клика по ссылке будет происходить плавный скролл до элемента. Реализуем это без использования плагинов сначала при помощи jQuery, а затем на чистом JavaScript.

Плавный скролл до якоря.

  1. С помощью jQuery.
  2. Для всех ссылок, начинающихся с #.
  3. На чистом JavaScript — метод Element.scrollIntoView().
  4. На чистом JavaScript — метод Window.scrollBy().

Сначала в HTML реализуем обычный «грубый» переход к секции, а затем уже добавим jQuery для создания плавности скролла.

Добавим id секциям к которым мы хотим выполнять скролл, а ссылкам атрибут href в формате #name. Решетка — означает идентификатор (id), а name — имя идентификатора.

HTML файл получится примерно такой.

<nav class="scrollto">
    <ul>
        <li><a href="#element1">Ссылка-1</a></li>
        <li><a href="#element2">Ссылка-2</a></li>
        <li><a href="#element3">Ссылка-3</a></li>
    </ul>
</nav>

<section id="element1">Секция-1</section>
<section id="element2">Секция-2</section>
<section id="element3">Секция-3</section>

Атрибут href указывает к какому элементу необходимо осуществить переход.

1. Плавный скролл с помощью jQuery

Теперь добавим плавности с помощью jQuery. В js-файле добавьте следующи код.

$(".scrollto a").on("click", function () {
    let href = $(this).attr("href");

    $("html, body").animate({
        scrollTop: $(href).offset().top
    }, {
        duration: 370,   // по умолчанию «400»
        easing: "linear" // по умолчанию «swing»
    });

    return false;
});

Чтобы добавить плавность перехода для необходимого элемента, просто добавьте навигации класс scrollto

Изменить скорость скролла можно поменяв значение duration

2. Плавный скролл для всех ссылок, начинающихся с #

Для этого мы обратимся к селектору атрибута тега a при помощи ^ — что будет означать, что мы выбираем все ссылки, начинающиеся с # (решётки)

$("a[href^='#']").on("click", function () {
    let href = $(this).attr("href");

    $("html, body").animate({
        scrollTop: $(href).offset().top
    });

    return false;
});

3. Плавный скролл на чистом JavaScript — метод Element.scrollIntoView()

Будем использовать метод scrollIntoView(). Это стандартный нативный метод JavaScript.

const smoothLinks = document.querySelectorAll("a[href^='#']");
for (let smoothLink of smoothLinks) {
    smoothLink.addEventListener("click", function (e) {
        e.preventDefault();
        const id = smoothLink.getAttribute("href");

        document.querySelector(id).scrollIntoView({
            behavior: "smooth",
            block: "start"
        });
    });
};

У метода scrollIntoView() есть недостаток.

Если у нас будет навигация position: fixed, то нам необходимо добавить отступ сверху на x-пикселей, т.е. высоту навигации.

Для решения данной задачи отлично подойдёт метод Window.scrollBy().

4. Плавный скролл на чистом JavaScript — метод Window.scrollBy()

Метод Window.scrollBy() имеет параметр top в котором мы укажем количество пикселей, на сколько нам необходимо прокрутить страницу.

От общей высоты документа отнимем высоту навигации и получим необходимое смещение в пикселях по оси Y.

document.querySelectorAll("a[href^='#']").forEach(link => {
    link.addEventListener("click", function (e) {
        e.preventDefault();
        let href = this.getAttribute("href").substring(1);
        const scrollTarget = document.getElementById(href);
        const topOffset = document.querySelector(".scrollto").offsetHeight;
        // const topOffset = 0; // если не нужен отступ сверху
        const elementPosition = scrollTarget.getBoundingClientRect().top;
        const offsetPosition = elementPosition - topOffset;

        window.scrollBy({
            top: offsetPosition,
            behavior: "smooth"
        });
    });
});

Если нужен отступ сверху, укажите class элемента (навигации), чтобы вычислить его высоту. Если не нужен отступ, переменной topOffset присвойте значение 0.