ScrollTop animation sans jquery

J'essaie de faire un effet animé "scroll to top" sans utiliser jQuery.

Dans jQuery, j'utilise habituellement ce code:

$('#go-to-top').click(function(){ $('html,body').animate({ scrollTop: 0 }, 400); return false; }); 

Comment puis-je animer scrollTop sans utiliser jQuery?

HTML:

 <button onclick="scrollToTop(1000);"></button> 

1 # JavaScript (linéaire):

 function scrollToTop(scrollDuration) { var scrollStep = -window.scrollY / (scrollDuration / 15), scrollInterval = setInterval(function(){ if ( window.scrollY != 0 ) { window.scrollBy( 0, scrollStep ); } else clearInterval(scrollInterval); },15); } 

2 # JavaScript (facilité d'entrée et de sortie):

 function scrollToTop(scrollDuration) { const scrollHeight = window.scrollY, scrollStep = Math.PI / ( scrollDuration / 15 ), cosParameter = scrollHeight / 2; var scrollCount = 0, scrollMargin, scrollInterval = setInterval( function() { if ( window.scrollY != 0 ) { scrollCount = scrollCount + 1; scrollMargin = cosParameter - cosParameter * Math.cos( scrollCount * scrollStep ); window.scrollTo( 0, ( scrollHeight - scrollMargin ) ); } else clearInterval(scrollInterval); }, 15 ); } 

Remarque:

  • Durée en millisecondes (1000 ms = 1 s)
  • Le deuxième script utilise la fonction cos. Exemple de courbe :

Entrez la description de l'image ici

En raison de la quantité élevée d'électeurs ascendants, j'ai vérifié mon code que j'ai écrit il y a quelques années et essayé de l'optimiser. De plus, j'ai ajouté une petite explication mathématique au bas de mon code.

MISE À JOUR (facilité d'entrée et de sortie):

Pour une diapositive / animation plus fluide, effectuée avec la méthode requestAnimationFrame. (Un peu de bégaiement se produit sur de grandes fenêtres, car le navigateur doit redessiner une vaste zone)

 function scrollToTop(scrollDuration) { var cosParameter = window.scrollY / 2, scrollCount = 0, oldTimestamp = performance.now(); function step (newTimestamp) { scrollCount += Math.PI / (scrollDuration / (newTimestamp - oldTimestamp)); if (scrollCount >= Math.PI) window.scrollTo(0, 0); if (window.scrollY === 0) return; window.scrollTo(0, Math.round(cosParameter + cosParameter * Math.cos(scrollCount))); oldTimestamp = newTimestamp; window.requestAnimationFrame(step); } window.requestAnimationFrame(step); } /* Explanations: - pi is the length/end point of the cosinus intervall (see above) - newTimestamp indicates the current time when callbacks queued by requestAnimationFrame begin to fire. (for more information see https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame) - newTimestamp - oldTimestamp equals the duration a * cos (bx + c) + d | c translates along the x axis = 0 = a * cos (bx) + d | d translates along the y axis = 1 -> only positive y values = a * cos (bx) + 1 | a stretches along the y axis = cosParameter = window.scrollY / 2 = cosParameter + cosParameter * (cos bx) | b stretches along the x axis = scrollCount = Math.PI / (scrollDuration / (newTimestamp - oldTimestamp)) = cosParameter + cosParameter * (cos scrollCount * x) */