scrollintoview动画

问题描述 投票:29回答:8

我的代码在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。有任何想法吗?谢谢。

scroll smooth js-scrollintoview
8个回答
2
投票

有一个jQuery插件正是为了这个

这里是链接to a blog post of mine,它描述了整个事情并且链接到GitHub项目,你可以在其中获得插件。

Animated scrollintoview() jQuery plugin.


56
投票

在大多数现代浏览器(Chrome and Firefox, but not Safari, UC, or IE)中,您可以将对象中的选项传递给.scrollIntoView()

试试这个:

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

其他值是behavior: 'instant'block: 'start'block: 'end'。见https://developer.mozilla.org/en/docs/Web/API/Element/scrollIntoView


30
投票

我也在搜索这个问题并找到了这个解决方案:

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

资源:http://www.abeautifulsite.net/smoothly-scroll-to-an-element-without-a-jquery-plugin-2/


13
投票

也许您不想仅为实现此功能而添加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);   
}

7
投票

使用requestAnimationFrame在特定持续时间内平滑滚动而不使用jQuery。

但是:ぁzxswい

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) (deltaTime)越来越大,它应该加速,并且随着dt越来越小而减速。如果用户滚动但我认为我打破了循环。全局变量阻止先前的调用完全接管,但不会取消先前的递归循环,因此它的动画速度会快两倍。


3
投票

你只需要包含这个polyfill就可以了。

distanceLeft

https://github.com/iamdustan/smoothscroll

或者如果你使用npm则需要它。

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

使用本机scrollIntoView方法。

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

2
投票

试试这个:

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

1
投票

只是为了增加它,以防它帮助某人,

我正在开发适用于iOS和Android的PWA,并使用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(); } 方法,直到我发现Safari不支持scrollIntoView()对象,因此不会平滑滚动或任何其他等。

我能够模仿scrollIntoViewOptions的功能,带有平滑滚动和“最近”选项,适用于iOS的普通JS ......好吧,普通的TypeScript ......

单击处理程序或w / e:

scrollIntoView

手动滚动功能:

const element = *elementToScrollIntoView*;
const scrollLayer = *layerToDoTheScrolling*

if (/iPad|iPhone|iPod/.test(navigator.userAgent) {
    let position;
    const top = element.offsetTop - scrollLayer.scrollTop;
    if (element.offsetTop < scrollLayer.scrollTop) {
            // top of element is above top of view - scroll to top of element
        position = element.offsetTop;
    } else if (element.scrollHeight + top < scrollLayer.offsetHeight) {
            // element is in view - don't need to scroll
        return;
    } else if (element.scrollHeight > scrollLayer.offsetHeight) {
            // element is bigger than view - scroll to top of element
        position = element.offsetTop;
    } else {
            // element partially cut-off - scroll remainder into view
        const difference = scrollLayer.offsetHeight - (element.scrollHeight + top);
        position = scrollLayer.scrollTop - difference;
    }
        // custom function for iOS
    scrollToElement(scrollLayer, position, 200);
} else {
        // just use native function for Android
    element.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'nearest' });
}

注意:处理程序中的大嵌套if和计算只是为了找到'最近'的位置,因为我试图复制该行为,但只是使用scrollToElement函数来动画滚动到顶部(默认行为没有Options对象)你可以使用:

scrollToElement(scrollLayer, destination, duration) {
    if (duration <= 0) {
        return;
    }
    const difference = destination - scrollLayer.scrollTop;
    const perTick = (difference / duration) * 10;

    setTimeout(() => {
        scrollLayer.scrollTop = scrollLayer.scrollTop + perTick;
        if (scrollLayer.scrollTop === destination) {
            return;
        }
        scrollToElement(scrollLayer, destination, duration - 10);
    }, 10);
}
© www.soinside.com 2019 - 2024. All rights reserved.