Skip to content

Instantly share code, notes, and snippets.

@nicholasaiello
Created October 3, 2017 19:18
Show Gist options
  • Save nicholasaiello/63a91af2de6d0eaca9e7aec38737b766 to your computer and use it in GitHub Desktop.
Save nicholasaiello/63a91af2de6d0eaca9e7aec38737b766 to your computer and use it in GitHub Desktop.
ES6 scrollTo
// Linear scrollTo
// used more than once, so better off in function
const getNowTimestamp = () => (
'now' in window.performance ? performance.now() : +new Date
);
const scrollTo = (dest, duration = 300, callback) => {
const body = document.body,
docElement = document.documentElement;
const titleOffset = 48,
startY = window.pageYOffset,
startTime = getNowTimestamp();
const docHeight = Math.max(body.scrollHeight, body.offsetHeight, docElement.clientHeight, docElement.scrollHeight, docElement.offsetHeight);
const winHeight = window.innerHeight || docElement.clientHeight || body.clientHeight;
const destOffset = (typeof dest === 'number' ? dest : dest.offsetTop) - titleOffset;
const destOffsetToScroll = Math.round(docHeight - destOffset < winHeight ? docHeight - winHeight : destOffset);
const scroll = () => {
const now = getNowTimestamp();
const time = Math.min(1, ((now - startTime) / duration));
window.scroll(0, Math.ceil((time * (destOffsetToScroll - startY)) + startY));
if (window.pageYOffset === destOffsetToScroll) {
if (callback) {
callback();
}
return;
}
requestAnimationFrame(scroll);
}
scroll();
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment