UPD: Ho creato un pacchetto npm che funziona meglio della seguente soluzione e più facile da usare.
La mia funzione smoothScroll
Ho preso la meravigliosa soluzione di Steve Banton e ho scritto una funzione che lo rende più comodo da usare. Sarebbe più semplice da usare window.scroll()
o addirittura window.scrollBy()
, come ho provato prima, ma questi due hanno alcuni problemi:
- Tutto diventa scadente dopo averli usati con un comportamento regolare.
- Non puoi impedirli comunque e devi aspettare fino alla fine del rotolo. Quindi spero che la mia funzione ti sia utile. Inoltre, c'è un polyfill leggero che lo fa funzionare in Safari e persino in IE.
Ecco il codice
Basta copiarlo e rovinarlo come vuoi.
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));
};
Per creare un elemento di collegamento è sufficiente aggiungere il seguente attributo di dati:
data-smooth-scroll-to="element-id"
Inoltre puoi impostare un altro attributo come aggiunta
data-smooth-scroll-block="center"
Rappresenta l' block
opzione della scrollIntoView()
funzione. Per impostazione predefinita, è start
. Maggiori informazioni su MDN .
Finalmente
Adatta la funzione smoothScroll alle tue esigenze.
Ad esempio, se hai un'intestazione fissa (o la chiamo con la parola masthead
) puoi fare qualcosa del genere:
const mastheadEl = document.querySelector(someMastheadSelector);
// and add it's height to the EXTRA_OFFSET variable
const EXTRA_OFFSET = mastheadEl.offsetHeight - 3;
Se non hai un caso del genere, eliminalo, perché no MrGreen.
scrollIntoView
è preoccupante.