|
105 | 105 | return scrollable;
|
106 | 106 | };
|
107 | 107 |
|
| 108 | + var rRelative = /^([\-\+]=)(\d+)/; |
108 | 109 | $.fn.extend({
|
109 | 110 | scrollable: function(dir) {
|
110 | 111 | var scrl = getScrollable.call(this, {dir: dir});
|
|
203 | 204 | }
|
204 | 205 | });
|
205 | 206 |
|
| 207 | + var getExplicitOffset = function(val) { |
| 208 | + var explicit = {relative: ''}; |
| 209 | + var parts = typeof val === 'string' && rRelative.exec(val); |
| 210 | + |
| 211 | + if (typeof val === 'number') { |
| 212 | + explicit.px = val; |
| 213 | + } else if (parts) { |
| 214 | + explicit.relative = parts[1]; |
| 215 | + explicit.px = parseFloat(parts[2]) || 0; |
| 216 | + } |
| 217 | + |
| 218 | + return explicit; |
| 219 | + }; |
| 220 | + |
206 | 221 | $.smoothScroll = function(options, px) {
|
207 | 222 | if (options === 'options' && typeof px === 'object') {
|
208 | 223 | return $.extend(optionOverrides, px);
|
209 | 224 | }
|
210 |
| - var opts, $scroller, scrollTargetOffset, speed, delta; |
| 225 | + var opts, $scroller, speed, delta; |
| 226 | + var explicitOffset = getExplicitOffset(options); |
| 227 | + var scrollTargetOffset = {}; |
211 | 228 | var scrollerOffset = 0;
|
212 | 229 | var offPos = 'offset';
|
213 | 230 | var scrollDir = 'scrollTop';
|
214 | 231 | var aniProps = {};
|
215 | 232 | var aniOpts = {};
|
216 | 233 |
|
217 |
| - if (typeof options === 'number') { |
| 234 | + console.log(explicitOffset); |
| 235 | + |
| 236 | + if (explicitOffset.px) { |
218 | 237 | opts = $.extend({link: null}, $.fn.smoothScroll.defaults, optionOverrides);
|
219 |
| - scrollTargetOffset = options; |
220 | 238 | } else {
|
221 | 239 | opts = $.extend({link: null}, $.fn.smoothScroll.defaults, options || {}, optionOverrides);
|
222 | 240 |
|
|
227 | 245 | opts.scrollElement.css('position', 'relative');
|
228 | 246 | }
|
229 | 247 | }
|
| 248 | + |
| 249 | + if (px) { |
| 250 | + explicitOffset = getExplicitOffset(px); |
| 251 | + } |
230 | 252 | }
|
231 | 253 |
|
232 | 254 | scrollDir = opts.direction === 'left' ? 'scrollLeft' : scrollDir;
|
233 | 255 |
|
234 | 256 | if (opts.scrollElement) {
|
235 | 257 | $scroller = opts.scrollElement;
|
236 | 258 |
|
237 |
| - if (!(/^(?:HTML|BODY)$/).test($scroller[0].nodeName)) { |
| 259 | + if (!explicitOffset.px && !(/^(?:HTML|BODY)$/).test($scroller[0].nodeName)) { |
238 | 260 | scrollerOffset = $scroller[scrollDir]();
|
239 | 261 | }
|
240 | 262 | } else {
|
|
244 | 266 | // beforeScroll callback function must fire before calculating offset
|
245 | 267 | opts.beforeScroll.call($scroller, opts);
|
246 | 268 |
|
247 |
| - scrollTargetOffset = (typeof options === 'number') ? options : |
248 |
| - px || |
249 |
| - ($(opts.scrollTarget)[offPos]() && |
250 |
| - $(opts.scrollTarget)[offPos]()[opts.direction]) || |
251 |
| - 0; |
| 269 | + scrollTargetOffset = explicitOffset.px ? explicitOffset : { |
| 270 | + relative: '', |
| 271 | + px: ($(opts.scrollTarget)[offPos]() && $(opts.scrollTarget)[offPos]()[opts.direction]) || 0 |
| 272 | + }; |
| 273 | + |
| 274 | + aniProps[scrollDir] = scrollTargetOffset.relative + (scrollTargetOffset.px + scrollerOffset + opts.offset); |
252 | 275 |
|
253 |
| - aniProps[scrollDir] = scrollTargetOffset + scrollerOffset + opts.offset; |
254 | 276 | speed = opts.speed;
|
255 | 277 |
|
256 | 278 | // automatically calculate the speed of the scroll based on distance / coefficient
|
|
0 commit comments