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.