scrollintoview анимации

мой код на http://jsfiddle.net/mannagod/QT3v5/7/.

JS:

function delay() {
    var INTENDED_MONTH = 7 //August
    // INTENDED_MONTH is zero-relative
    now = new Date().getDate(),
rows = document.getElementById('scripture').rows;
    if (new Date().getMonth() != INTENDED_MONTH) {
        // need a value here less than 1, 
        // or the box for the first of the month will be in Red
        now = 0.5
    };
    for (var i = 0, rl = rows.length; i < rl; i++) {
        var cells = rows[i].childNodes;
        for (j = 0, cl = cells.length; j < cl; j++) {
            if (cells[j].nodeName == 'TD'
  && cells[j].firstChild.nodeValue != ''
  && cells[j].firstChild.nodeValue == now) {
                // 'ffff99' // '#ffd700' // TODAY - red
                rows[i].style.backgroundColor = 'red' 
                rows[i].scrollIntoView();
            }
        }
    }
}

мне нужно найти способ, чтобы сгладить .scrollintoview(). Прямо сейчас он "прыгает" в выделенную строку. Мне нужно, чтобы он плавно перешел в этот ряд. Это необходимо сделать динамически в замене scrollintoview. Есть идеи? Спасибо.

7 ответов


для этого есть плагин jQuery

вот ссылка на мой пост в блоге это описывает все это и имеет ссылку на проект GitHub, где вы можете получить плагин.

анимация scrollintoview() плагин jQuery.


Я тоже искал эту проблему и нашли такое решение:

$('html, body').animate({
    scrollTop: $("#elementId").offset().top
}, 1000);

ресурс: http://www.abeautifulsite.net/smoothly-scroll-to-an-element-without-a-jquery-plugin-2/


в большинстве современных браузеров (Chrome и Firefox, но не Safari, UC или IE) вы можете передать параметры в объекте в .scrollIntoView().

попробуйте это:

elm.scrollIntoView({ behavior: 'smooth', block: 'center' })

другие значения behavior: 'instant' или block: 'start' или block: 'end'. См.https://developer.mozilla.org/en/docs/Web/API/Element/scrollIntoView


возможно, вы не хотите добавлять jQuery только для реализации этой функции. elem - это элемент для прокрутки. Целевой pos может быть взят из свойства offsetTop элемента, который будет перемещен в представление.

function Scroll_To(elem, pos)
{
    var y = elem.scrollTop;
    y += (pos - y) * 0.3;
    if (Math.abs(y-pos) < 2)
    {
        elem.scrollTop = pos;
        return;
    }
    elem.scrollTop = y;
    setTimeout(Scroll_To, 40, elem, pos);   
}

плавная прокрутка с помощью requestAnimationFrame в течение определенной продолжительности без jQuery.

демо:http://codepen.io/Shadeness/pen/XXyvKG?editors=0010

window.bringIntoView_started = 0;
window.bringIntoView_ends = 0;
window.bringIntoView_y = 0;
window.bringIntoView_tick = function() {
  var distanceLeft, dt, duration, t, travel;
  t = Date.now();
  if (t < window.bringIntoView_ends) {
    dt = t - window.bringIntoView_started;
    duration = window.bringIntoView_ends - window.bringIntoView_started;
    distanceLeft = window.bringIntoView_y - document.body.scrollTop;
      travel = distanceLeft * (dt / duration);
      document.body.scrollTop += travel;
      window.requestAnimationFrame(window.bringIntoView_tick);
  } else {
    document.body.scrollTop = window.bringIntoView_y;
  }
};
window.bringIntoView = function(e, duration) {
  window.bringIntoView_started = Date.now();
  window.bringIntoView_ends = window.bringIntoView_started + duration;
  window.bringIntoView_y = Math.min(document.body.scrollTop + e.getBoundingClientRect().top, document.body.scrollHeight - window.innerHeight);
  window.requestAnimationFrame(window.bringIntoView_tick);
};

например:

bringIntoView(document.querySelector('#bottom'), 400)

он должен ускоряться как dt (deltaTime) становится больше и замедляется как distanceLeft сделать меньше. Я подумал о разрыве цикла, если пользователь прокрутил, но meh. Глобальные переменные предотвращают полный захват предыдущего вызова, но не отменяют предыдущий рекурсивный цикл, поэтому он будет анимироваться в два раза быстрее.


вам просто нужно включить этот polyfill, и он работает.

https://github.com/iamdustan/smoothscroll

<script src="js/smoothscroll.js"></script>

или требуется, если вы используете npm.

require('smoothscroll-polyfill').polyfill();

используйте собственный метод scrollIntoView.

document.getElementById('parallax-group-logo').scrollIntoView({
    block: "start",
    behavior: "smooth"
});

попробуйте это:

function scroll_into_view_smooth(elem)
{   var FPS = 48; // frames per second
    var DURATION = 0.6; // sec
    var e = elem;
    var left = e.offsetLeft;
    var top = e.offsetTop;
    var width = e.offsetWidth;
    var height = e.offsetHeight;
    var body = document.body;
    var to_scroll = [];
    var p, offset;
    while ((p = e.offsetParent))
    {   var client_width = p.clientWidth;
        var client_height = p!=body ? p.clientHeight : Math.min(document.documentElement.clientHeight, window.innerHeight);
        if (client_width<p.scrollWidth-1 && ((offset=left-p.scrollLeft)<0 || (offset=left+width-p.scrollLeft-client_width)>0))
        {   to_scroll.push({elem: p, prop: 'scrollLeft', from: p.scrollLeft, offset: offset});
        }
        if (client_height<p.scrollHeight-1 && ((offset=top-p.scrollTop)<0 || (offset=top+height-p.scrollTop-client_height)>0))
        {   to_scroll.push({elem: p, prop: 'scrollTop', from: p.scrollTop, offset: offset});
        }
        e = p;
        left += e.offsetLeft;
        top += e.offsetTop;
    }
    var x = 0;
    function apply()
    {   x = Math.min(x+1/(DURATION * FPS), 1);
        for (var i=to_scroll.length-1; i>=0; i--)
        {   to_scroll[i].elem[to_scroll[i].prop] = to_scroll[i].from + to_scroll[i].offset*x*x;
        }
        if (x < 1)
        {   setTimeout(apply, 1000/FPS);
        }
    }
    apply();
}