JSFiddle - React, Tailwind, and code Playground
HTML
<html>
<head>
</head>
<body>
<a href="#bottom" onclick="scroll.go2id('bottom');return false;" >Go Bottom</a>
<P style="height:4000px"></P>
<a id="bottom" href="#" onclick="scroll.go2top();return false;" >Go Top</a>
</body>
</html>
CSS
body {
background: -moz-linear-gradient(top, rgba(30,87,153,1) 0%, rgba(89,148,202,1) 62%, rgba(95,154,207,0.7) 68%, rgba(125,185,232,0) 100%); /* FF3.6-15 */
background: -webkit-linear-gradient(top, rgba(30,87,153,1) 0%,rgba(89,148,202,1) 62%,rgba(95,154,207,0.7) 68%,rgba(125,185,232,0) 100%); /* Chrome10-25,Safari5.1-6 */
background: linear-gradient(to bottom, rgba(30,87,153,1) 0%,rgba(89,148,202,1) 62%,rgba(95,154,207,0.7) 68%,rgba(125,185,232,0) 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#1e5799', endColorstr='#007db9e8',GradientType=0 ); /* IE6-9 */
}
JavaScript
var scroll = {
iterr: 30, // miliseconds
tm: null,
reset_timer: function () { // reset
if (this.tm) {
clearTimeout(this.tm);
this.tm = null;
}
this.iterr = 30;
},
realtop_of: function (el) {
var elm = el;
var realTop = 0;
do {
realTop += elm.offsetTop;
elm = elm.offsetParent;
} while (elm);
return realTop;
},
pagescroll: function () {
var yOff = window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop;
return yOff;
},
go2top: function () {
return scroll.go2elem(document.body);
},
go2id: function (id) {
var targetEl = document.getElementById(id);
return scroll.go2elem(targetEl);
},
go2elem: function (targetEl) {
var eOff = targetEl.offsetTop;
var tOff = this.realtop_of(targetEl.parentNode);
return scroll.go2pos(eOff, tOff);
},
go2pos: function (eOff, tOff) {
// scroll to tha element with the given id.
// eOff : beginning point
// tOff : terminus point
this.reset_timer();
var pOff, scrVal, pos, dir, step;
pOff = this.pagescroll();
if (pOff === null || isNaN(pOff) || pOff === 'undefined') pOff = 0;
scrVal = eOff - pOff; // scroll amount
if (scrVal > tOff) {
pos = (eOff - tOff - pOff);
dir = 1;
}
if (scrVal < tOff) {
pos = (pOff + tOff) - eOff;
dir = -1;
}
if (scrVal !== tOff) {
step = ~~((pos / 4) + 1) * dir;
this.iterr = (this.iterr > 1) ? this.iterr - 1: 0;
window.scrollBy(0, step);
this.tm = window.setTimeout(function () {
scroll.go2pos(eOff, tOff);
}, this.iterr);
}
if (scrVal === tOff) {
this.reset_timer();
}
}
};
window.scroll = scroll;