Skip to content

Instantly share code, notes, and snippets.

@EvgenyOrekhov
Last active February 21, 2016 16:07
Show Gist options
  • Save EvgenyOrekhov/6bd0ec240eeca082f73b to your computer and use it in GitHub Desktop.
Save EvgenyOrekhov/6bd0ec240eeca082f73b to your computer and use it in GitHub Desktop.
A convenient "toTop" function for your "Scroll to top and back" button
/*jslint browser: true */
/*jshint laxbreak: true */
/*global requestAnimationFrame */
/**
* A convenient "toTop" function for your "Scroll to top and back" button.
* Animates page scroll to the page top,
* or to the specified "top" coordinate,
* or to the specified element's top.
* On the next click on your button, if the page hasn't been scrolled,
* the function scrolls the page to the previous scroll position.
*
* @see {@link https://jsfiddle.net/tqftkggt/4/ demo}
*
* @author EvgenyOrekhov
*
* @example <caption>Attach the behavior to an element
* with id="myToTopButton".</caption>
* toTop("#myToTopButton");
*
* @example <caption>Attach the behavior to an element
* with id="myToTopButton"
* and make it scroll to the top of the element
* with id="content".</caption>
* toTop("#myToTopButton", "#content");
*
* @example <caption>Attach the behavior to an element
* and set the "top" coordinate to 100px.</caption>
* toTop(anElement, 100);
*
* @param {(string|Object)} button - Your "scroll to top" button's selector
* or the button element itself.
* @param {number|string|Object} [top=0] - The optional "top" coordinate,
* or the selector for the element to the top of which to scroll to,
* or the element itself.
*/
function toTop(button, top) {
"use strict";
var lastScrollTop = document.documentElement.scrollTop
|| document.body.scrollTop;
function run(top) {
var remainingPixels = 40;
var stepSize = 4;
var currentScrollTop = document.documentElement.scrollTop
|| document.body.scrollTop;
var maxTop = document.body.scrollHeight
- document.documentElement.clientHeight;
function scrollNextStep() {
var nextScrollTop = top + remainingPixels;
document.body.scrollTop = nextScrollTop;
document.documentElement.scrollTop = nextScrollTop;
if (remainingPixels !== 0) {
remainingPixels -= stepSize;
requestAnimationFrame(scrollNextStep);
}
}
if (top && top.getBoundingClientRect !== undefined) {
top = top.getBoundingClientRect().top + currentScrollTop;
top = Math.round(top);
}
if (isNaN(top) || top < 0) {
top = 0;
}
if (top === currentScrollTop) {
top = lastScrollTop;
}
if (top > maxTop) {
top = maxTop;
}
if (currentScrollTop < top) {
remainingPixels = -remainingPixels;
stepSize = -stepSize;
}
lastScrollTop = currentScrollTop;
requestAnimationFrame(scrollNextStep);
}
if (typeof button === "string") {
button = document.querySelector(button);
}
if (typeof top === "string") {
top = document.querySelector(top);
}
button.addEventListener("click", function () {
run(top);
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment