In jQuery you can do things like
$(\'html, body\').stop().animate({
\'scrollTop\': $target.offset().top
}, 1000);
And I\'m interested h
This question is usually answered with a function utilizing setInterval
/ setTimeout
and scrolling the element in tiny increments, see: Cross browser JavaScript (not jQuery...) scroll to top animation
I'd like to propose another, more modern way of doing it using dynamically added CSS transition, which should be smoother and less CPU-hungry. It animates the body
using CSS, JavaScript only calculates and sets translateY()
transform on the element. After the CSS animation finishes the transform is removed and scroll position is set.
Demo: http://jsfiddle.net/00uw1Lq9/4/ (updated link after cross-browser fixes).
Works only in browsers with unprefixed transitions and transforms (tested in IE11, current Chrome and Firefox), for older versions you may need to add prefix detection. It's also probably broken in some ways, treat it as a starting point, not a solution.
// this function self-initializes and attaches an event listener to the root element
var smoothScroll = (function(root){
//keep track of the target element between scrolling function and transitionend callback
var targetElement;
// called when the CSS transition finishes
root.addEventListener('transitionend', function(e){
// remove transition and transform
root.style['transition'] = '';
root.style['transform'] = '';
// do the actual scrolling
targetElement.scrollIntoView();
});
// this function fill be available as the smoothScroll function
return function(element, time){
// get the top position of target element
var offset = element.offsetTop - root.scrollTop;
// if the element is very low it can't get scrolled up to the top of the window
offset = Math.min( offset, root.offsetHeight - document.documentElement.clientHeight );
// save reference to the target element for callback
targetElement = element;
// set transfor/transition CSS properties
root.style['transition'] = 'transform';
root.style['transition-duration'] = time;
// this fakes the scrolling animation by animating transform on the element
root.style['transform'] = 'translateY(' + offset * -1 +'px)';
}
}(document.body));
Usage: smothScroll( DOMNodeReference, time )
, where time
is a string valid for CSS transition-duration
property (for example '300ms'
or '2.5s'
).