UPD: я создал пакет npm, который работает лучше, чем следующее решение, и более прост в использовании.
Моя функция smoothScroll
Я взял замечательное решение Стива Бентона и написал функцию, которая делает его более удобным в использовании. Было бы проще использовать window.scroll()
или даже window.scrollBy()
, как я пробовал раньше, но у этих двоих есть некоторые проблемы:
- Все становится бесполезным после их использования с плавным поведением.
- Вы ни в коем случае не можете предотвратить их, и вам придется подождать до и свитка. Надеюсь, моя функция будет вам полезна. Также есть легкий полифилл, который позволяет ему работать в Safari и даже в IE.
Вот код
Просто скопируйте это и возитесь с этим, как хотите.
import smoothscroll from 'smoothscroll-polyfill';
smoothscroll.polyfill();
const prepareSmoothScroll = linkEl => {
const EXTRA_OFFSET = 0;
const destinationEl = document.getElementById(linkEl.dataset.smoothScrollTo);
const blockOption = linkEl.dataset.smoothScrollBlock || 'start';
if ((blockOption === 'start' || blockOption === 'end') && EXTRA_OFFSET) {
const anchorEl = document.createElement('div');
destinationEl.setAttribute('style', 'position: relative;');
anchorEl.setAttribute('style', `position: absolute; top: -${EXTRA_OFFSET}px; left: 0;`);
destinationEl.appendChild(anchorEl);
linkEl.addEventListener('click', () => {
anchorEl.scrollIntoView({
block: blockOption,
behavior: 'smooth',
});
});
}
if (blockOption === 'center' || !EXTRA_OFFSET) {
linkEl.addEventListener('click', () => {
destinationEl.scrollIntoView({
block: blockOption,
behavior: 'smooth',
});
});
}
};
export const activateSmoothScroll = () => {
const linkEls = [...document.querySelectorAll('[data-smooth-scroll-to]')];
linkEls.forEach(linkEl => prepareSmoothScroll(linkEl));
};
Чтобы создать элемент ссылки, просто добавьте следующий атрибут данных:
data-smooth-scroll-to="element-id"
Также вы можете установить другой атрибут в качестве дополнения
data-smooth-scroll-block="center"
Он представляет собой block
вариант scrollIntoView()
функции. По умолчанию это start
. Узнать больше о MDN .
в заключение
Настройте функцию smoothScroll в соответствии с вашими потребностями.
Например, если у вас есть фиксированный заголовок (или я называю его словом masthead
), вы можете сделать что-то вроде этого:
const mastheadEl = document.querySelector(someMastheadSelector);
// and add it's height to the EXTRA_OFFSET variable
const EXTRA_OFFSET = mastheadEl.offsetHeight - 3;
Если у вас нет такого дела, то просто удалите его, почему бы и нет :-D.
scrollIntoView
.