Плавная прокрутка в javascript?

В jQuery вы можете делать такие вещи, как

$('html, body').stop().animate({
    'scrollTop': $target.offset().top
}, 1000);

И мне интересно, как обращаться с этим только в Javascript?

Спасибо!

Ответ 1

На этот вопрос обычно отвечает функция, использующая setInterval/setTimeout и прокручивая элемент с небольшими приращениями, см. Перекрестный браузер JavaScript (не jQuery...) прокрутка к началу анимации

Я хотел бы предложить другой, более современный способ сделать это, используя динамически добавленный переход CSS, который должен быть более плавным и менее голодным. Он анимирует body с помощью CSS, JavaScript только вычисляет и устанавливает преобразование translateY() в элементе. После завершения анимации CSS преобразование удаляется и устанавливается положение прокрутки.

Демо: http://jsfiddle.net/00uw1Lq9/4/ (обновленная ссылка после исправлений в браузере).

Работает только в браузерах с незафиксированными переходами и преобразованиями (протестировано в IE11, текущем Chrome и Firefox), для более старых версий вам может потребоваться добавить обнаружение префикса. Он также, вероятно, сломан в некотором смысле, рассматривает его как отправную точку, а не решение.

// 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));

Использование: smothScroll( DOMNodeReference, time ), где time - строка, действительная для свойства CSS transition-duration (например, '300ms' или '2.5s').