141 lines
3.7 KiB
JavaScript
141 lines
3.7 KiB
JavaScript
|
import $ from 'jquery';
|
||
|
import { GetYoDigits } from './foundation.core.utils';
|
||
|
import { Plugin } from './foundation.core.plugin';
|
||
|
|
||
|
/**
|
||
|
* SmoothScroll module.
|
||
|
* @module foundation.smooth-scroll
|
||
|
*/
|
||
|
class SmoothScroll extends Plugin {
|
||
|
/**
|
||
|
* Creates a new instance of SmoothScroll.
|
||
|
* @class
|
||
|
* @name SmoothScroll
|
||
|
* @fires SmoothScroll#init
|
||
|
* @param {Object} element - jQuery object to add the trigger to.
|
||
|
* @param {Object} options - Overrides to the default plugin settings.
|
||
|
*/
|
||
|
_setup(element, options) {
|
||
|
this.$element = element;
|
||
|
this.options = $.extend({}, SmoothScroll.defaults, this.$element.data(), options);
|
||
|
this.className = 'SmoothScroll'; // ie9 back compat
|
||
|
|
||
|
this._init();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Initialize the SmoothScroll plugin
|
||
|
* @private
|
||
|
*/
|
||
|
_init() {
|
||
|
const id = this.$element[0].id || GetYoDigits(6, 'smooth-scroll');
|
||
|
this.$element.attr({ id });
|
||
|
|
||
|
this._events();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Initializes events for SmoothScroll.
|
||
|
* @private
|
||
|
*/
|
||
|
_events() {
|
||
|
this.$element.on('click.zf.smoothScroll', this._handleLinkClick)
|
||
|
this.$element.on('click.zf.smoothScroll', 'a[href^="#"]', this._handleLinkClick);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Handle the given event to smoothly scroll to the anchor pointed by the event target.
|
||
|
* @param {*} e - event
|
||
|
* @function
|
||
|
* @private
|
||
|
*/
|
||
|
_handleLinkClick(e) {
|
||
|
// Follow the link if it does not point to an anchor.
|
||
|
if (!$(e.currentTarget).is('a[href^="#"]')) return;
|
||
|
|
||
|
const arrival = e.currentTarget.getAttribute('href');
|
||
|
|
||
|
this._inTransition = true;
|
||
|
|
||
|
SmoothScroll.scrollToLoc(arrival, this.options, () => {
|
||
|
this._inTransition = false;
|
||
|
});
|
||
|
|
||
|
e.preventDefault();
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Function to scroll to a given location on the page.
|
||
|
* @param {String} loc - A properly formatted jQuery id selector. Example: '#foo'
|
||
|
* @param {Object} options - The options to use.
|
||
|
* @param {Function} callback - The callback function.
|
||
|
* @static
|
||
|
* @function
|
||
|
*/
|
||
|
static scrollToLoc(loc, options = SmoothScroll.defaults, callback) {
|
||
|
const $loc = $(loc);
|
||
|
|
||
|
// Do nothing if target does not exist to prevent errors
|
||
|
if (!$loc.length) return false;
|
||
|
|
||
|
var scrollPos = Math.round($loc.offset().top - options.threshold / 2 - options.offset);
|
||
|
|
||
|
$('html, body').stop(true).animate(
|
||
|
{ scrollTop: scrollPos },
|
||
|
options.animationDuration,
|
||
|
options.animationEasing,
|
||
|
() => {
|
||
|
if (typeof callback === 'function'){
|
||
|
callback();
|
||
|
}
|
||
|
}
|
||
|
);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Destroys the SmoothScroll instance.
|
||
|
* @function
|
||
|
*/
|
||
|
_destroy() {
|
||
|
this.$element.off('click.zf.smoothScroll', this._handleLinkClick)
|
||
|
this.$element.off('click.zf.smoothScroll', 'a[href^="#"]', this._handleLinkClick);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Default settings for plugin.
|
||
|
*/
|
||
|
SmoothScroll.defaults = {
|
||
|
/**
|
||
|
* Amount of time, in ms, the animated scrolling should take between locations.
|
||
|
* @option
|
||
|
* @type {number}
|
||
|
* @default 500
|
||
|
*/
|
||
|
animationDuration: 500,
|
||
|
/**
|
||
|
* Animation style to use when scrolling between locations. Can be `'swing'` or `'linear'`.
|
||
|
* @option
|
||
|
* @type {string}
|
||
|
* @default 'linear'
|
||
|
* @see {@link https://api.jquery.com/animate|Jquery animate}
|
||
|
*/
|
||
|
animationEasing: 'linear',
|
||
|
/**
|
||
|
* Number of pixels to use as a marker for location changes.
|
||
|
* @option
|
||
|
* @type {number}
|
||
|
* @default 50
|
||
|
*/
|
||
|
threshold: 50,
|
||
|
/**
|
||
|
* Number of pixels to offset the scroll of the page on item click if using a sticky nav bar.
|
||
|
* @option
|
||
|
* @type {number}
|
||
|
* @default 0
|
||
|
*/
|
||
|
offset: 0
|
||
|
}
|
||
|
|
||
|
export {SmoothScroll}
|