|
5 | 5 | * Licensed MIT
|
6 | 6 | */
|
7 | 7 |
|
8 |
| -(function (factory) { |
| 8 | +(function(factory) { |
9 | 9 | if (typeof define === 'function' && define.amd) {
|
10 | 10 | // AMD. Register as an anonymous module.
|
11 | 11 | define(['jquery'], factory);
|
|
16 | 16 | // Browser globals
|
17 | 17 | factory(jQuery);
|
18 | 18 | }
|
19 |
| -}(function ($) { |
| 19 | +}(function($) { |
20 | 20 |
|
21 |
| - var version = '1.6.1', |
22 |
| - optionOverrides = {}, |
23 |
| - defaults = { |
24 |
| - exclude: [], |
25 |
| - excludeWithin: [], |
26 |
| - offset: 0, |
| 21 | + var version = '1.6.1'; |
| 22 | + var optionOverrides = {}; |
| 23 | + var defaults = { |
| 24 | + exclude: [], |
| 25 | + excludeWithin: [], |
| 26 | + offset: 0, |
27 | 27 |
|
28 |
| - // one of 'top' or 'left' |
29 |
| - direction: 'top', |
| 28 | + // one of 'top' or 'left' |
| 29 | + direction: 'top', |
30 | 30 |
|
31 |
| - // if set, bind click events through delegation |
32 |
| - // supported since jQuery 1.4.2 |
33 |
| - delegateSelector: null, |
| 31 | + // if set, bind click events through delegation |
| 32 | + // supported since jQuery 1.4.2 |
| 33 | + delegateSelector: null, |
34 | 34 |
|
35 |
| - // jQuery set of elements you wish to scroll (for $.smoothScroll). |
36 |
| - // if null (default), $('html, body').firstScrollable() is used. |
37 |
| - scrollElement: null, |
| 35 | + // jQuery set of elements you wish to scroll (for $.smoothScroll). |
| 36 | + // if null (default), $('html, body').firstScrollable() is used. |
| 37 | + scrollElement: null, |
38 | 38 |
|
39 |
| - // only use if you want to override default behavior |
40 |
| - scrollTarget: null, |
| 39 | + // only use if you want to override default behavior |
| 40 | + scrollTarget: null, |
41 | 41 |
|
42 |
| - // fn(opts) function to be called before scrolling occurs. |
43 |
| - // `this` is the element(s) being scrolled |
44 |
| - beforeScroll: function() {}, |
| 42 | + // fn(opts) function to be called before scrolling occurs. |
| 43 | + // `this` is the element(s) being scrolled |
| 44 | + beforeScroll: function() {}, |
45 | 45 |
|
46 |
| - // fn(opts) function to be called after scrolling occurs. |
47 |
| - // `this` is the triggering element |
48 |
| - afterScroll: function() {}, |
49 |
| - easing: 'swing', |
50 |
| - speed: 400, |
| 46 | + // fn(opts) function to be called after scrolling occurs. |
| 47 | + // `this` is the triggering element |
| 48 | + afterScroll: function() {}, |
| 49 | + easing: 'swing', |
| 50 | + speed: 400, |
51 | 51 |
|
52 |
| - // coefficient for "auto" speed |
53 |
| - autoCoefficient: 2, |
| 52 | + // coefficient for "auto" speed |
| 53 | + autoCoefficient: 2, |
54 | 54 |
|
55 |
| - // $.fn.smoothScroll only: whether to prevent the default click action |
56 |
| - preventDefault: true |
57 |
| - }, |
| 55 | + // $.fn.smoothScroll only: whether to prevent the default click action |
| 56 | + preventDefault: true |
| 57 | + }; |
58 | 58 |
|
59 |
| - getScrollable = function(opts) { |
60 |
| - var scrollable = [], |
61 |
| - scrolled = false, |
62 |
| - dir = opts.dir && opts.dir === 'left' ? 'scrollLeft' : 'scrollTop'; |
| 59 | + var getScrollable = function(opts) { |
| 60 | + var scrollable = []; |
| 61 | + var scrolled = false; |
| 62 | + var dir = opts.dir && opts.dir === 'left' ? 'scrollLeft' : 'scrollTop'; |
63 | 63 |
|
64 |
| - this.each(function() { |
65 |
| - var el = $(this); |
| 64 | + this.each(function() { |
| 65 | + var el = $(this); |
66 | 66 |
|
67 |
| - if (this === document || this === window) { |
68 |
| - return; |
69 |
| - } |
| 67 | + if (this === document || this === window) { |
| 68 | + return; |
| 69 | + } |
70 | 70 |
|
71 |
| - if ( document.scrollingElement && (this === document.documentElement || this === document.body) ) { |
72 |
| - scrollable.push(document.scrollingElement); |
| 71 | + if (document.scrollingElement && (this === document.documentElement || this === document.body)) { |
| 72 | + scrollable.push(document.scrollingElement); |
73 | 73 |
|
74 |
| - return false; |
75 |
| - } |
| 74 | + return false; |
| 75 | + } |
76 | 76 |
|
77 |
| - if ( el[dir]() > 0 ) { |
78 |
| - scrollable.push(this); |
79 |
| - } else { |
80 |
| - // if scroll(Top|Left) === 0, nudge the element 1px and see if it moves |
81 |
| - el[dir](1); |
82 |
| - scrolled = el[dir]() > 0; |
83 |
| - if ( scrolled ) { |
84 |
| - scrollable.push(this); |
85 |
| - } |
86 |
| - // then put it back, of course |
87 |
| - el[dir](0); |
88 |
| - } |
89 |
| - }); |
| 77 | + if (el[dir]() > 0) { |
| 78 | + scrollable.push(this); |
| 79 | + } else { |
| 80 | + // if scroll(Top|Left) === 0, nudge the element 1px and see if it moves |
| 81 | + el[dir](1); |
| 82 | + scrolled = el[dir]() > 0; |
90 | 83 |
|
91 |
| - // If no scrollable elements, fall back to <body>, |
92 |
| - // if it's in the jQuery collection |
93 |
| - // (doing this because Safari sets scrollTop async, |
94 |
| - // so can't set it to 1 and immediately get the value.) |
95 |
| - if (!scrollable.length) { |
96 |
| - this.each(function() { |
97 |
| - if (this.nodeName === 'BODY') { |
98 |
| - scrollable = [this]; |
99 |
| - } |
100 |
| - }); |
| 84 | + if (scrolled) { |
| 85 | + scrollable.push(this); |
101 | 86 | }
|
102 |
| - |
103 |
| - // Use the first scrollable element if we're calling firstScrollable() |
104 |
| - if ( opts.el === 'first' && scrollable.length > 1 ) { |
105 |
| - scrollable = [ scrollable[0] ]; |
| 87 | + // then put it back, of course |
| 88 | + el[dir](0); |
| 89 | + } |
| 90 | + }); |
| 91 | + |
| 92 | + // If no scrollable elements, fall back to <body>, |
| 93 | + // if it's in the jQuery collection |
| 94 | + // (doing this because Safari sets scrollTop async, |
| 95 | + // so can't set it to 1 and immediately get the value.) |
| 96 | + if (!scrollable.length) { |
| 97 | + this.each(function() { |
| 98 | + if (this.nodeName === 'BODY') { |
| 99 | + scrollable = [this]; |
106 | 100 | }
|
| 101 | + }); |
| 102 | + } |
107 | 103 |
|
108 |
| - return scrollable; |
109 |
| - }; |
| 104 | + // Use the first scrollable element if we're calling firstScrollable() |
| 105 | + if (opts.el === 'first' && scrollable.length > 1) { |
| 106 | + scrollable = [scrollable[0]]; |
| 107 | + } |
| 108 | + |
| 109 | + return scrollable; |
| 110 | + }; |
110 | 111 |
|
111 | 112 | $.fn.extend({
|
112 | 113 | scrollable: function(dir) {
|
113 | 114 | var scrl = getScrollable.call(this, {dir: dir});
|
| 115 | + |
114 | 116 | return this.pushStack(scrl);
|
115 | 117 | },
|
116 | 118 | firstScrollable: function(dir) {
|
117 | 119 | var scrl = getScrollable.call(this, {el: 'first', dir: dir});
|
| 120 | + |
118 | 121 | return this.pushStack(scrl);
|
119 | 122 | },
|
120 | 123 |
|
121 | 124 | smoothScroll: function(options, extra) {
|
122 | 125 | options = options || {};
|
123 | 126 |
|
124 |
| - if ( options === 'options' ) { |
125 |
| - if ( !extra ) { |
| 127 | + if (options === 'options') { |
| 128 | + if (!extra) { |
126 | 129 | return this.first().data('ssOpts');
|
127 | 130 | }
|
| 131 | + |
128 | 132 | return this.each(function() {
|
129 |
| - var $this = $(this), |
130 |
| - opts = $.extend($this.data('ssOpts') || {}, extra); |
| 133 | + var $this = $(this); |
| 134 | + var opts = $.extend($this.data('ssOpts') || {}, extra); |
131 | 135 |
|
132 | 136 | $(this).data('ssOpts', opts);
|
133 | 137 | });
|
|
136 | 140 | var opts = $.extend({}, $.fn.smoothScroll.defaults, options);
|
137 | 141 |
|
138 | 142 | var clickHandler = function(event) {
|
139 |
| - var link = this, |
140 |
| - $link = $(this), |
141 |
| - thisOpts = $.extend({}, opts, $link.data('ssOpts') || {}), |
142 |
| - exclude = opts.exclude, |
143 |
| - excludeWithin = thisOpts.excludeWithin, |
144 |
| - elCounter = 0, ewlCounter = 0, |
145 |
| - include = true, |
146 |
| - clickOpts = {}, |
147 |
| - locationPath = $.smoothScroll.filterPath(location.pathname), |
148 |
| - linkPath = $.smoothScroll.filterPath(link.pathname), |
149 |
| - hostMatch = ((location.hostname === link.hostname) || !link.hostname), |
150 |
| - pathMatch = thisOpts.scrollTarget || ( linkPath === locationPath ), |
151 |
| - thisHash = escapeSelector(link.hash); |
152 |
| - |
153 |
| - if ( !thisOpts.scrollTarget && (!hostMatch || !pathMatch || !thisHash) ) { |
| 143 | + var escapeSelector = function(str) { |
| 144 | + return str.replace(/(:|\.|\/)/g, '\\$1'); |
| 145 | + }; |
| 146 | + |
| 147 | + var link = this; |
| 148 | + var $link = $(this); |
| 149 | + var thisOpts = $.extend({}, opts, $link.data('ssOpts') || {}); |
| 150 | + var exclude = opts.exclude; |
| 151 | + var excludeWithin = thisOpts.excludeWithin; |
| 152 | + var elCounter = 0; |
| 153 | + var ewlCounter = 0; |
| 154 | + var include = true; |
| 155 | + var clickOpts = {}; |
| 156 | + var locationPath = $.smoothScroll.filterPath(location.pathname); |
| 157 | + var linkPath = $.smoothScroll.filterPath(link.pathname); |
| 158 | + var hostMatch = location.hostname === link.hostname || !link.hostname; |
| 159 | + var pathMatch = thisOpts.scrollTarget || (linkPath === locationPath); |
| 160 | + var thisHash = escapeSelector(link.hash); |
| 161 | + |
| 162 | + if (!thisOpts.scrollTarget && (!hostMatch || !pathMatch || !thisHash)) { |
154 | 163 | include = false;
|
155 | 164 | } else {
|
156 | 165 | while (include && elCounter < exclude.length) {
|
157 | 166 | if ($link.is(escapeSelector(exclude[elCounter++]))) {
|
158 | 167 | include = false;
|
159 | 168 | }
|
160 | 169 | }
|
161 |
| - while ( include && ewlCounter < excludeWithin.length ) { |
| 170 | + |
| 171 | + while (include && ewlCounter < excludeWithin.length) { |
162 | 172 | if ($link.closest(excludeWithin[ewlCounter++]).length) {
|
163 | 173 | include = false;
|
164 | 174 | }
|
165 | 175 | }
|
166 | 176 | }
|
167 | 177 |
|
168 |
| - if ( include ) { |
169 |
| - |
170 |
| - if ( thisOpts.preventDefault ) { |
| 178 | + if (include) { |
| 179 | + if (thisOpts.preventDefault) { |
171 | 180 | event.preventDefault();
|
172 | 181 | }
|
173 | 182 |
|
174 |
| - $.extend( clickOpts, thisOpts, { |
| 183 | + $.extend(clickOpts, thisOpts, { |
175 | 184 | scrollTarget: thisOpts.scrollTarget || thisHash,
|
176 | 185 | link: link
|
177 | 186 | });
|
178 | 187 |
|
179 |
| - $.smoothScroll( clickOpts ); |
| 188 | + $.smoothScroll(clickOpts); |
180 | 189 | }
|
181 | 190 | };
|
182 | 191 |
|
183 | 192 | if (options.delegateSelector !== null) {
|
184 | 193 | this
|
185 |
| - .undelegate(options.delegateSelector, 'click.smoothscroll') |
186 |
| - .delegate(options.delegateSelector, 'click.smoothscroll', clickHandler); |
| 194 | + .undelegate(options.delegateSelector, 'click.smoothscroll') |
| 195 | + .delegate(options.delegateSelector, 'click.smoothscroll', clickHandler); |
187 | 196 | } else {
|
188 | 197 | this
|
189 |
| - .unbind('click.smoothscroll') |
190 |
| - .bind('click.smoothscroll', clickHandler); |
| 198 | + .unbind('click.smoothscroll') |
| 199 | + .bind('click.smoothscroll', clickHandler); |
191 | 200 | }
|
192 | 201 |
|
193 | 202 | return this;
|
194 | 203 | }
|
195 | 204 | });
|
196 | 205 |
|
197 | 206 | $.smoothScroll = function(options, px) {
|
198 |
| - if ( options === 'options' && typeof px === 'object' ) { |
| 207 | + if (options === 'options' && typeof px === 'object') { |
199 | 208 | return $.extend(optionOverrides, px);
|
200 | 209 | }
|
201 |
| - var opts, $scroller, scrollTargetOffset, speed, delta, |
202 |
| - scrollerOffset = 0, |
203 |
| - offPos = 'offset', |
204 |
| - scrollDir = 'scrollTop', |
205 |
| - aniProps = {}, |
206 |
| - aniOpts = {}; |
| 210 | + var opts, $scroller, scrollTargetOffset, speed, delta; |
| 211 | + var scrollerOffset = 0; |
| 212 | + var offPos = 'offset'; |
| 213 | + var scrollDir = 'scrollTop'; |
| 214 | + var aniProps = {}; |
| 215 | + var aniOpts = {}; |
207 | 216 |
|
208 | 217 | if (typeof options === 'number') {
|
209 | 218 | opts = $.extend({link: null}, $.fn.smoothScroll.defaults, optionOverrides);
|
210 | 219 | scrollTargetOffset = options;
|
211 | 220 | } else {
|
212 | 221 | opts = $.extend({link: null}, $.fn.smoothScroll.defaults, options || {}, optionOverrides);
|
| 222 | + |
213 | 223 | if (opts.scrollElement) {
|
214 | 224 | offPos = 'position';
|
| 225 | + |
215 | 226 | if (opts.scrollElement.css('position') === 'static') {
|
216 | 227 | opts.scrollElement.css('position', 'relative');
|
217 | 228 | }
|
|
220 | 231 |
|
221 | 232 | scrollDir = opts.direction === 'left' ? 'scrollLeft' : scrollDir;
|
222 | 233 |
|
223 |
| - if ( opts.scrollElement ) { |
| 234 | + if (opts.scrollElement) { |
224 | 235 | $scroller = opts.scrollElement;
|
225 |
| - if ( !(/^(?:HTML|BODY)$/).test($scroller[0].nodeName) ) { |
| 236 | + |
| 237 | + if (!(/^(?:HTML|BODY)$/).test($scroller[0].nodeName)) { |
226 | 238 | scrollerOffset = $scroller[scrollDir]();
|
227 | 239 | }
|
228 | 240 | } else {
|
|
234 | 246 |
|
235 | 247 | scrollTargetOffset = (typeof options === 'number') ? options :
|
236 | 248 | px ||
|
237 |
| - ( $(opts.scrollTarget)[offPos]() && |
238 |
| - $(opts.scrollTarget)[offPos]()[opts.direction] ) || |
| 249 | + ($(opts.scrollTarget)[offPos]() && |
| 250 | + $(opts.scrollTarget)[offPos]()[opts.direction]) || |
239 | 251 | 0;
|
240 | 252 |
|
241 | 253 | aniProps[scrollDir] = scrollTargetOffset + scrollerOffset + opts.offset;
|
|
274 | 286 | $.smoothScroll.version = version;
|
275 | 287 | $.smoothScroll.filterPath = function(string) {
|
276 | 288 | string = string || '';
|
| 289 | + |
277 | 290 | return string
|
278 |
| - .replace(/^\//,'') |
279 |
| - .replace(/(?:index|default).[a-zA-Z]{3,4}$/,'') |
280 |
| - .replace(/\/$/,''); |
| 291 | + .replace(/^\//, '') |
| 292 | + .replace(/(?:index|default).[a-zA-Z]{3,4}$/, '') |
| 293 | + .replace(/\/$/, ''); |
281 | 294 | };
|
282 | 295 |
|
283 | 296 | // default options
|
284 | 297 | $.fn.smoothScroll.defaults = defaults;
|
285 | 298 |
|
286 |
| - function escapeSelector (str) { |
287 |
| - return str.replace(/(:|\.|\/)/g,'\\$1'); |
288 |
| - } |
289 |
| - |
290 | 299 | }));
|
291 |
| - |
|
0 commit comments