64 lines
2.2 KiB
JavaScript
64 lines
2.2 KiB
JavaScript
import { isNumeric } from './is'
|
||
|
||
let isAnimating = false;
|
||
|
||
const defaults = {
|
||
easing: 'swing',
|
||
headerOffset: 60,
|
||
speed: 300
|
||
};
|
||
|
||
/**
|
||
* scrollTo is a function that scrolls a container to an element's position within that controller
|
||
* Uses jQuery's $.Deferred to allow using a callback on animation completion
|
||
* @param {object} $element A jQuery node
|
||
* @param {object} options
|
||
*/
|
||
export function scrollTo($element, options) {
|
||
const deferred = $.Deferred();
|
||
|
||
// Drop everything if this ain't a jQuery object
|
||
if ($element instanceof jQuery && $element.length > 0) {
|
||
|
||
// Merging options
|
||
options = $.extend({}, defaults, (typeof options !== 'undefined' ? options : {}));
|
||
|
||
// Prevents accumulation of animations
|
||
if (isAnimating === false) {
|
||
isAnimating = true;
|
||
|
||
// Default container that we'll be scrolling
|
||
let $container = $('html, body');
|
||
let elementOffset = 0;
|
||
|
||
// Testing container in options for jQuery-ness
|
||
// If we're not using a custom container, we take the top document offset
|
||
// If we are, we use the elements position relative to the container
|
||
if (typeof options.$container !== 'undefined' && options.$container instanceof jQuery && options.$container.length > 0) {
|
||
$container = options.$container;
|
||
|
||
if (typeof options.scrollTop !== 'undefined' && isNumeric(options.scrollTop) && options.scrollTop !== 0) {
|
||
scrollTop = options.scrollTop;
|
||
} else {
|
||
scrollTop = $element.position().top - options.headerOffset;
|
||
}
|
||
} else {
|
||
if (typeof options.scrollTop !== 'undefined' && isNumeric(options.scrollTop) && options.scrollTop !== 0) {
|
||
scrollTop = options.scrollTop;
|
||
} else {
|
||
scrollTop = $element.offset().top - options.headerOffset;
|
||
}
|
||
}
|
||
|
||
$container.animate({
|
||
scrollTop: scrollTop
|
||
}, options.speed, options.easing, function() {
|
||
isAnimating = false;
|
||
deferred.resolve();
|
||
});
|
||
}
|
||
}
|
||
|
||
return deferred.promise();
|
||
}
|