Решил написать для себя небольшую заметку, редко, но бывает, что нужно сделать плавную прокрутку по нажатию ссылки к якорю на странице. Раньше я использовал способ написанный на jQuery
, сейчас он также актуален и выглядит так:
var $page = $('html, body');
$('a[href*="#"]').click(function() {
$page.animate({
scrollTop: $($.attr(this, 'href')).offset().top
}, 400);
return false;
});
Есть также код написаный на чистом javascript. Выглядит он так:
/** Переход по якорным ссылкам */
document.querySelectorAll('a[href*="#"]').forEach(anchor => anchor.addEventListener("click", function (e) {
const anchorTargetID = anchor.getAttribute("href").substring(1);
const $anchorTarget = document.getElementById(anchorTargetID);
if (!$anchorTarget) return;
e.preventDefault();
$anchorTarget.scrollIntoView({ behavior: "smooth", block: "start" });
}));
что в первом, что во втором случае код срабатывает на ссылки вида:
<a href="#anchor-1">Ссылка к якорю 1</a>
и перемещает к блоку с id
anchor-1
<div id="anchor-1"> ... </div>
Скролл по якорным ссылкам с учетом высоты элементов
Если при скролле нужно учитывать высоту каких либо элементов, то код будет следующим:
/** Скролл по якорным ссылкам с учетом элементов с классом .js-margin-scroll */
const anchors = document.querySelectorAll('a[href*="#"]');
anchors.forEach(anchor => {
anchor.addEventListener("click", function (e) {
if(!document.getElementById(this.getAttribute('href').substr(1))) return;
e.preventDefault();
const $blockTo = document.getElementById(this.getAttribute('href').substr(1));
const marginScroll = Array.from(document.querySelectorAll(".js-margin-scroll")).map(item => item.offsetHeight).reduce((prev, current) => prev + current) || 0;
window.scrollTo({ top: $blockTo.offsetTop - marginScroll, behavior: "smooth" });
})
});
/** --- Скролл по якорным ссылкам с учетом элементов с классом .js-margin-scroll */
А для учета элементов, высоту которых надо учесть, надо добавить им класс js-margin-scroll
.