Skip to content

Commit 3662175

Browse files
committed
Add src
1 parent d33815b commit 3662175

File tree

1 file changed

+210
-0
lines changed

1 file changed

+210
-0
lines changed

src/jquery.smooth-scroll.js

Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
(function($) {
2+
3+
var version = '@VERSION',
4+
defaults = {
5+
exclude: [],
6+
excludeWithin:[],
7+
offset: 0,
8+
direction: 'top', // one of 'top' or 'left'
9+
scrollElement: null, // jQuery set of elements you wish to scroll (for $.smoothScroll).
10+
// if null (default), $('html, body').firstScrollable() is used.
11+
scrollTarget: null, // only use if you want to override default behavior
12+
beforeScroll: function() {}, // fn(opts) function to be called before scrolling occurs. "this" is the element(s) being scrolled
13+
afterScroll: function() {}, // fn(opts) function to be called after scrolling occurs. "this" is the triggering element
14+
easing: 'swing',
15+
speed: 400,
16+
autoCoefficent: 2 // coefficient for "auto" speed
17+
},
18+
19+
getScrollable = function(opts) {
20+
var scrollable = [],
21+
scrolled = false,
22+
dir = opts.dir && opts.dir == 'left' ? 'scrollLeft' : 'scrollTop';
23+
24+
this.each(function() {
25+
26+
if (this == document || this == window) { return; }
27+
var el = $(this);
28+
if ( el[dir]() > 0 ) {
29+
scrollable.push(this);
30+
} else {
31+
// if scroll(Top|Left) === 0, nudge the element 1px and see if it moves
32+
el[dir](1);
33+
scrolled = el[dir]() > 0;
34+
if ( scrolled ) {
35+
scrollable.push(this);
36+
}
37+
// then put it back, of course
38+
el[dir](0);
39+
}
40+
});
41+
42+
// If no scrollable elements, fall back to <body>,
43+
// if it's in the jQuery collection
44+
// (doing this because Safari sets scrollTop async,
45+
// so can't set it to 1 and immediately get the value.)
46+
if (!scrollable.length) {
47+
this.each(function(index) {
48+
if (this.nodeName === 'BODY') {
49+
scrollable = [this];
50+
}
51+
});
52+
}
53+
54+
// Use the first scrollable element if we're calling firstScrollable()
55+
if ( opts.el === 'first' && scrollable.length > 1 ) {
56+
scrollable = [ scrollable[0] ];
57+
}
58+
59+
return scrollable;
60+
},
61+
isTouch = 'ontouchend' in document;
62+
63+
$.fn.extend({
64+
scrollable: function(dir) {
65+
var scrl = getScrollable.call(this, {dir: dir});
66+
return this.pushStack(scrl);
67+
},
68+
firstScrollable: function(dir) {
69+
var scrl = getScrollable.call(this, {el: 'first', dir: dir});
70+
return this.pushStack(scrl);
71+
},
72+
73+
smoothScroll: function(options) {
74+
options = options || {};
75+
var opts = $.extend({}, $.fn.smoothScroll.defaults, options),
76+
locationPath = $.smoothScroll.filterPath(location.pathname);
77+
78+
this
79+
.unbind('click.smoothscroll')
80+
.bind('click.smoothscroll', function(event) {
81+
var link = this,
82+
$link = $(this),
83+
exclude = opts.exclude,
84+
excludeWithin = opts.excludeWithin,
85+
elCounter = 0, ewlCounter = 0,
86+
include = true,
87+
clickOpts = {},
88+
hostMatch = ((location.hostname === link.hostname) || !link.hostname),
89+
pathMatch = opts.scrollTarget || ( $.smoothScroll.filterPath(link.pathname) || locationPath ) === locationPath,
90+
thisHash = escapeSelector(link.hash);
91+
92+
if ( !opts.scrollTarget && (!hostMatch || !pathMatch || !thisHash) ) {
93+
include = false;
94+
} else {
95+
while (include && elCounter < exclude.length) {
96+
if ($link.is(escapeSelector(exclude[elCounter++]))) {
97+
include = false;
98+
}
99+
}
100+
while ( include && ewlCounter < excludeWithin.length ) {
101+
if ($link.closest(excludeWithin[ewlCounter++]).length) {
102+
include = false;
103+
}
104+
}
105+
}
106+
107+
if ( include ) {
108+
event.preventDefault();
109+
110+
$.extend( clickOpts, opts, {
111+
scrollTarget: opts.scrollTarget || thisHash,
112+
link: link
113+
});
114+
115+
$.smoothScroll( clickOpts );
116+
}
117+
});
118+
119+
return this;
120+
}
121+
});
122+
123+
$.smoothScroll = function(options, px) {
124+
var opts, $scroller, scrollTargetOffset, speed,
125+
scrollerOffset = 0,
126+
offPos = 'offset',
127+
scrollDir = 'scrollTop',
128+
aniProps = {},
129+
aniOpts = {},
130+
scrollprops = [];
131+
132+
if ( typeof options === 'number') {
133+
opts = $.fn.smoothScroll.defaults;
134+
scrollTargetOffset = options;
135+
} else {
136+
opts = $.extend({}, $.fn.smoothScroll.defaults, options || {});
137+
if (opts.scrollElement) {
138+
offPos = 'position';
139+
if (opts.scrollElement.css('position') == 'static') {
140+
opts.scrollElement.css('position', 'relative');
141+
}
142+
}
143+
144+
scrollTargetOffset = px ||
145+
( $(opts.scrollTarget)[offPos]() &&
146+
$(opts.scrollTarget)[offPos]()[opts.direction] ) ||
147+
0;
148+
}
149+
150+
opts = $.extend({link: null}, opts);
151+
scrollDir = opts.direction == 'left' ? 'scrollLeft' : scrollDir;
152+
153+
if ( opts.scrollElement ) {
154+
$scroller = opts.scrollElement;
155+
scrollerOffset = $scroller[scrollDir]();
156+
} else {
157+
$scroller = $('html, body').firstScrollable();
158+
}
159+
160+
aniProps[scrollDir] = scrollTargetOffset + scrollerOffset + opts.offset;
161+
162+
opts.beforeScroll.call($scroller, opts);
163+
164+
speed = opts.speed;
165+
166+
// automatically calculate the speed of the scroll based on distance / coefficient
167+
if (speed === 'auto') {
168+
169+
// if aniProps[scrollDir] == 0 then we'll use scrollTop() value instead
170+
speed = aniProps[scrollDir] || $scroller.scrollTop();
171+
172+
// divide the speed by the coefficient
173+
speed = speed / opts.autoCoefficent;
174+
}
175+
176+
aniOpts = {
177+
duration: speed,
178+
easing: opts.easing,
179+
complete: function() {
180+
opts.afterScroll.call(opts.link, opts);
181+
}
182+
};
183+
184+
if (opts.step) {
185+
aniOpts.step = opts.step;
186+
}
187+
188+
if ($scroller.length) {
189+
$scroller.stop().animate(aniProps, aniOpts);
190+
} else {
191+
opts.afterScroll.call(opts.link, opts);
192+
}
193+
};
194+
195+
$.smoothScroll.version = version;
196+
$.smoothScroll.filterPath = function(string) {
197+
return string
198+
.replace(/^\//,'')
199+
.replace(/(index|default).[a-zA-Z]{3,4}$/,'')
200+
.replace(/\/$/,'');
201+
};
202+
203+
// default options
204+
$.fn.smoothScroll.defaults = defaults;
205+
206+
function escapeSelector (str) {
207+
return str.replace(/(:|\.)/g,'\\$1');
208+
}
209+
210+
})(jQuery);

0 commit comments

Comments
 (0)