-
Notifications
You must be signed in to change notification settings - Fork 5.5k
/
Copy pathfoundation.smoothScroll.js
141 lines (124 loc) · 3.81 KB
/
foundation.smoothScroll.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
import $ from 'jquery';
import { GetYoDigits } from './foundation.core.utils';
import { Plugin } from './foundation.core.plugin';
/**
* SmoothScroll module.
* @module foundation.smoothScroll
*/
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._linkClickListener = this._handleLinkClick.bind(this);
this.$element.on('click.zf.smoothScroll', this._linkClickListener);
this.$element.on('click.zf.smoothScroll', 'a[href^="#"]', this._linkClickListener);
}
/**
* 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._linkClickListener)
this.$element.off('click.zf.smoothScroll', 'a[href^="#"]', this._linkClickListener);
}
}
/**
* 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}