window.scroll smooth not working on Safari

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


More specifically in a JavaScript context, the unsupported part is the behavior parameter on scrollToOptions as detailed here:

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


window.scroll is supported, but scroll-behavior CSS is not.

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

Pending support, consider using the smoothscroll-polyfill which adds smooth scrolling support for Safari, IE, and Edge.