window.scroll平滑无法在Safari上运行

时间:2018-08-07 16:47:14

标签: javascript scroll

当用户单击按钮时,我正在使用它来平滑滚动到特定部分:

window.scroll({
  top: $(this).data('y'),
  left: 0,
  behavior: 'smooth'
});

这在所有地方(包括Android手机)都很好,但在Safari(台式机和iphone)上都很好。在这种情况下,它会滚动到正确的位置,但它不平滑,就像跳了起来。

我在here的Codepen上做了一个小型演示。只需单击导航菜单选项,它将在此处滚动。这在Chrome上会很流畅,但在Safari上不会。

不支持此功能吗? (looking at the doc似乎并非如此)受支持的选项是什么?

谢谢!

3 个答案:

答案 0 :(得分:0)

更具体地说,在JavaScript上下文中,不支持的部分是scrollToOptions上的-itsoffset参数,如此处所述:

https://developer.mozilla.org/en-US/docs/Web/API/Window/scroll

答案 1 :(得分:0)

I recently wrote down my ideas into a function, which is kind of polyfill for lacking smooth scroll feature support in IOS browsers and desktop Safari as well. Some may call it a bloody workaround, but hey, it's working. It doesn't require jQuery, it's pure javascript.

var fnc_scrollto = function(to,id){
    var smoothScrollFeature = 'scrollBehavior' in document.documentElement.style;
    var articles = document.querySelectorAll("ul#content > li"), i;
    if (to == 'elem') to = articles[id].offsetTop;
    var i = parseInt(window.pageYOffset);
    if ( i != to ) {
        if (!smoothScrollFeature) {
            to = parseInt(to);
            if (i < to) {
                var int = setInterval(function() {
                    if (i > (to-20)) i += 1;
                    else if (i > (to-40)) i += 3;
                    else if (i > (to-80)) i += 8;
                    else if (i > (to-160)) i += 18;
                    else if (i > (to-200)) i += 24;
                    else if (i > (to-300)) i += 40;
                    else i += 60;
                    window.scroll(0, i);
                    if (i >= to) clearInterval(int);
                }, 15);
            }
            else {
                var int = setInterval(function() {
                    if (i < (to+20)) i -= 1;
                    else if (i < (to+40)) i -= 3;
                    else if (i < (to+80)) i -= 8;
                    else if (i < (to+160)) i -= 18;
                    else if (i < (to+200)) i -= 24;
                    else if (i < (to+300)) i -= 40;
                    else i -= 60;
                    window.scroll(0, i);
                    if (i <= to) clearInterval(int);
                }, 15);
            }
        }
        else {
            window.scroll({
                top: to,
                left: 0,
                behavior: 'smooth'
            });
        }
    }
};

You may pass arguments to the function as numeric value (scollTo-position in pixels) or as a call of an element with index (in my case LI nodes in an UL --> "articles").

<a class="active" href="javascript:fnc_scrollto(0)">Home</a>
<a class="active" href="javascript:fnc_scrollto(457)">anywhere</a>
<a href="javascript:fnc_scrollto('elem',0)">element 1</a>
<a href="javascript:fnc_scrollto('elem',1)">element 2</a>

You may play around with the numbers to adapt the smooth effect to your needs. If you have a sticky navbar on top, you need to adapt the line

if (to == 'elem') to = articles[id].offsetTop;

to your needs like e.g.

if (to == 'elem') to = parseInt(articles[id].offsetTop-navbar.clientHeight);

Hope you like it :-)

答案 2 :(得分:-2)

支持

window.scroll,但不支持scroll-behavior CSS。

https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-behavior