UPD: He creado un paquete npm que funciona mejor que la siguiente solución y es más fácil de usar.
Mi función smoothScroll
Tomé la maravillosa solución de Steve Banton y escribí una función que la hace más conveniente de usar. Sería más fácil de usar window.scroll()
o incluso window.scrollBy()
, como lo intenté antes, pero estos dos tienen algunos problemas:
- Todo se vuelve basura después de usarlos con un comportamiento suave.
- No puedes evitarlos de todos modos y tienes que esperar hasta el y del pergamino. Así que espero que mi función te sea útil. Además, hay un polyfill ligero que lo hace funcionar en Safari e incluso en IE.
Aqui esta el codigo
Simplemente cópielo y límpielo con él como quiera.
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));
};
Para crear un elemento de enlace, simplemente agregue el siguiente atributo de datos:
data-smooth-scroll-to="element-id"
También puede establecer otro atributo como complemento
data-smooth-scroll-block="center"
Representa la block
opción de la scrollIntoView()
función. De forma predeterminada, es start
. Leer más sobre MDN .
Finalmente
Ajuste la función smoothScroll a sus necesidades.
Por ejemplo, si tiene algún encabezado fijo (o lo llamo con la palabra masthead
), puede hacer algo como esto:
const mastheadEl = document.querySelector(someMastheadSelector);
// and add it's height to the EXTRA_OFFSET variable
const EXTRA_OFFSET = mastheadEl.offsetHeight - 3;
Si no tiene tal caso, simplemente bórrelo, por qué no :-D.
scrollIntoView
es preocupante.