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
турбує.