代码之家  ›  专栏  ›  技术社区  ›  moondaisy

window.scroll smooth不在Safari上工作

  •  2
  • moondaisy  · 技术社区  · 6 年前

    当用户单击某个按钮时,我使用此功能可以平滑地滚动到特定的部分:

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

    这在任何地方都很有效(包括Android手机),但在Safari(台式机和iPhone)上除外。在这种情况下,它会滚动到正确的位置,但不平滑,就像是跳跃。

    我在codepen上做了一个小演示 here

    looking at the doc

    3 回复  |  直到 5 年前
        1
  •  -1
  •   tyriker    6 年前
        3
  •  0
  •   Community Erin Dees    5 年前

    我最近把我的想法写进了一个函数中,这个函数是一种polyfill,因为在iOS浏览器和桌面Safari中缺乏平滑的滚动功能支持。有些人可能会说这是一个血腥的解决方案,但嘿,这是有效的。它不需要jquery,它是纯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'
                });
            }
        }
    };
    

    您可以将参数作为数值(scollto position in pixels)或带有索引的元素调用(在我的例子中是ul-->“文章”中的li节点)传递给函数。

    <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>
    

    你可以玩弄数字来适应你的需求。 如果你在上面有一个粘性的导航条,你需要调整线路。

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

    满足您的需求,例如

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

    希望你喜欢——)