Skip to content

Instantly share code, notes, and snippets.

@hideya
Last active February 15, 2019 07:07
Show Gist options
  • Save hideya/f1e36c559a861e15008e39c81f1531da to your computer and use it in GitHub Desktop.
Save hideya/f1e36c559a861e15008e39c81f1531da to your computer and use it in GitHub Desktop.
Automatically make all anchors to an ID'ed in-page element to smooth-scroll
// Automatically make all anchors to an ID'ed in-page element to smooth-scroll
window.addEventListener('load', function(event) {
var duration = 300; // ms
var bias = 0; // px
var header = document.getElementsByTagName('header')[0];
if (header) {
bias = -header.getBoundingClientRect().height - 40;
}
var anchors = document.getElementsByTagName("a");
for (var i = 0, max = anchors.length; i < max; i++) {
var anchor = anchors[i];
var href = anchor.getAttribute("href");
if (href === null || !href.startsWith("#")) {
continue;
}
anchor.addEventListener("click", function(e) {
e.preventDefault();
var href = this.getAttribute("href");
window.history.pushState({name : href}, null, href);
var name = href.substring(1);
var target = document.getElementById(name);
scrollToElem(target, bias, duration);
});
}
});
// based on https://gist.github.com/andjosh/6764939
function scrollToElem(target, bias, duration) {
var start = window.pageYOffset;
var to = (!target) ? 0 : target.offsetTop + bias;
var change = to - start;
var currentTime = 0;
var increment = 20;
function animateScroll() {
currentTime += increment;
var val = easeInOutQuad(currentTime, start, change, duration);
window.scrollTo(window.pageXOffset, val);
if (currentTime < duration) {
setTimeout(animateScroll, increment);
}
};
animateScroll();
// t = current time
// b = start value
// c = change in value
// d = duration
function easeInOutQuad(t, b, c, d) {
t /= d / 2;
if (t < 1) return c / 2 * t * t + b;
t--;
return -c / 2 * (t * (t - 2) - 1) + b;
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment