UPD: Utworzyłem pakiet npm, który działa lepiej niż poniższe rozwiązanie i jest łatwiejszy w użyciu.
Moja funkcja smoothScroll
Wziąłem cudowne rozwiązanie Steve'a Bantona i napisałem funkcję, która sprawia, że jest wygodniejszy w użyciu. Byłoby łatwiejsze w użyciu, window.scroll()
a nawet window.scrollBy()
, jak próbowałem wcześniej, ale te dwa mają pewne problemy:
- Wszystko staje się niezdarne po ich użyciu z płynnym zachowaniem.
- W każdym razie nie możesz im zapobiec i musisz czekać do końca zwoju. Mam więc nadzieję, że moja funkcja będzie dla Ciebie przydatna. Jest też lekki polyfill, który sprawia, że działa w Safari, a nawet IE.
Oto kod
Po prostu skopiuj i zepsuć, jak chcesz.
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));
};
Aby utworzyć element odsyłacza, wystarczy dodać następujący atrybut danych:
data-smooth-scroll-to="element-id"
Możesz także ustawić inny atrybut jako dodatek
data-smooth-scroll-block="center"
Reprezentuje block
opcję scrollIntoView()
funkcji. Domyślnie jest to start
. Przeczytaj więcej na MDN .
Wreszcie
Dostosuj funkcję smoothScroll do swoich potrzeb.
Na przykład, jeśli masz jakiś stały nagłówek (lub nazywam to słowem masthead
), możesz zrobić coś takiego:
const mastheadEl = document.querySelector(someMastheadSelector);
// and add it's height to the EXTRA_OFFSET variable
const EXTRA_OFFSET = mastheadEl.offsetHeight - 3;
Jeśli nie masz takiego przypadku, po prostu go usuń, dlaczego nie :-D.
scrollIntoView
jest niepokojący.