Skip to content

Commit 92f675c

Browse files
author
Karl Swedberg
committed
added new method: .scrollable()
switched to .live() instead of .bind() made direction optional ('top' or 'left') general code cleanup/improvement allow for scrolling some element other than the "document" when using $.smoothScroll() ( as opposed to $('something').smoothScroll() )
1 parent ea1e317 commit 92f675c

File tree

1 file changed

+84
-70
lines changed

1 file changed

+84
-70
lines changed

jquery.smooth-scroll.js

Lines changed: 84 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* jQuery Smooth Scroll plugin
3-
* Version 1.1 (March 25, 2010)
3+
* Version 1.2 (July 6, 2010)
44
* @requires jQuery v1.3+
55
*
66
* Dual licensed under the MIT and GPL licenses (just like jQuery):
@@ -12,77 +12,109 @@
1212

1313
(function($) {
1414

15-
var version = '1.1';
15+
var version = '1.2';
1616

1717
var locationPath = filterPath(location.pathname);
1818

1919
$.fn.extend({
20-
smoothScroll: function(options) {
21-
20+
scrollable: function() {
21+
var scrollable = [], scrolled = false;
2222
this.each(function() {
23-
var opts = $.extend({}, $.fn.smoothScroll.defaults, options);
24-
25-
$(this).bind('click', function(event) {
26-
var link = this, $link = $(this),
27-
hostMatch = ((location.hostname === link.hostname) || !link.hostname),
28-
pathMatch = opts.scrollTarget || (filterPath(link.pathname) || locationPath) === locationPath,
29-
thisHash = link.hash && '#' + link.hash.replace('#',''),
30-
include = true;
31-
32-
33-
if (!opts.scrollTarget && (!hostMatch || !pathMatch || thisHash.length == 1) ) {
34-
include = false;
35-
} else {
36-
var exclude = opts.exclude, elCounter = 0, el = exclude.length;
37-
while (include && elCounter < el) {
38-
if ($link.is(exclude[elCounter++])) {
39-
include = false;
40-
}
41-
}
4223

43-
var excludeWithin = opts.excludeWithin, ewlCounter = 0, ewl = excludeWithin.length;
44-
while (include && ewlCounter < ewl) {
45-
if ($link.parents(excludeWithin[ewlCounter++] + ':first').length) {
46-
include = false;
47-
}
48-
}
24+
if (this == document || this == window) { return; }
25+
var el = $(this);
26+
if ( el.scrollTop() > 0 ) {
27+
scrollable = [this];
28+
return false;
29+
}
30+
31+
el.scrollTop(1);
32+
scrolled = el.scrollTop() > 0;
33+
el.scrollTop(0);
34+
if ( scrolled ) {
35+
scrollable = [this];
36+
return false;
37+
}
38+
39+
});
40+
41+
return this.pushStack(scrollable);
42+
},
43+
44+
smoothScroll: function(options) {
45+
var opts = $.extend({}, $.fn.smoothScroll.defaults, options);
46+
this.die('click.smoothscroll').live('click.smoothscroll', function(event) {
47+
48+
var link = this, $link = $(this),
49+
hostMatch = ((location.hostname === link.hostname) || !link.hostname),
50+
pathMatch = opts.scrollTarget || (filterPath(link.pathname) || locationPath) === locationPath,
51+
thisHash = link.hash && '#' + link.hash.replace('#',''),
52+
include = true;
53+
54+
55+
if (!opts.scrollTarget && (!hostMatch || !pathMatch || thisHash.length == 1) ) {
56+
include = false;
57+
} else {
58+
var exclude = opts.exclude, elCounter = 0, el = exclude.length;
59+
while (include && elCounter < el) {
60+
if ($link.is(exclude[elCounter++])) {
61+
include = false;
62+
}
4963
}
5064

51-
if (include) {
52-
opts.scrollTarget = opts.scrollTarget || thisHash;
53-
opts.link = link;
54-
event.preventDefault();
55-
$.smoothScroll(opts);
65+
var excludeWithin = opts.excludeWithin, ewlCounter = 0, ewl = excludeWithin.length;
66+
while (include && ewlCounter < ewl) {
67+
if ($link.closest(excludeWithin[ewlCounter++]).length) {
68+
include = false;
69+
}
5670
}
57-
});
71+
}
72+
73+
if (include) {
74+
opts.scrollTarget = opts.scrollTarget || thisHash;
75+
opts.link = link;
76+
event.preventDefault();
77+
$.smoothScroll(opts);
78+
}
5879
});
59-
80+
6081
return this;
6182

6283
}
63-
84+
6485
});
6586

6687
$.smoothScroll = function(options, px) {
67-
var opts,
68-
scrollTargetOffset,
69-
scrollElem = scrollableElement('html', 'body');
70-
88+
var opts, scrollTargetOffset, offPos = 'offset';
89+
7190
if ( typeof options === 'number') {
7291
opts = $.fn.smoothScroll.defaults;
7392
scrollTargetOffset = options;
7493
} else {
75-
opts = $.extend({}, $.fn.smoothScroll.defaults, options);
76-
scrollTargetOffset = px || $(opts.scrollTarget).offset() && $(opts.scrollTarget).offset().top || 0;
94+
opts = $.extend({}, $.fn.smoothScroll.defaults, options || {});
95+
if (opts.scrollElement) {
96+
offPos = 'position';
97+
if (opts.scrollElement.css('position') == 'static') {
98+
opts.scrollElement.css('position', 'relative');
99+
}
100+
}
101+
102+
scrollTargetOffset = px ||
103+
( $(opts.scrollTarget)[offPos]() &&
104+
$(opts.scrollTarget)[offPos]()[opts.direction] ) ||
105+
0;
77106
}
78107
opts = $.extend({link: null}, opts);
79-
80-
$(scrollElem).animate({
81-
scrollTop: scrollTargetOffset + opts.offset
82-
},
108+
109+
var $scroller = opts.scrollElement || $('html, body').scrollable(),
110+
dirs = {top: 'Top', 'left': 'Left'},
111+
aniprops = {};
112+
113+
aniprops['scroll' + dirs[opts.direction]] = scrollTargetOffset + opts.offset;
114+
$scroller.animate(aniprops,
83115
{
84116
duration: opts.speed,
85-
easing: opts.easing,
117+
easing: opts.easing,
86118
complete: function() {
87119
if ( opts.afterScroll && $.isFunction(opts.afterScroll) ) {
88120
opts.afterScroll.call(opts.link, opts);
@@ -99,35 +131,17 @@ $.fn.smoothScroll.defaults = {
99131
exclude: [],
100132
excludeWithin:[],
101133
offset: 0,
134+
direction: 'top', // one of 'top' or 'left'
135+
scrollElement: null, // jQuery set of elements you wish to scroll.
136+
//if null (default), $('html, body').scrollable() is used.
102137
scrollTarget: null, // only use if you want to override default behavior
103138
afterScroll: null, // function to be called after window is scrolled. "this" is the triggering element
104139
easing: 'swing',
105140
speed: 400
106141
};
107142

108143

109-
// private functions
110-
111-
// don't pass window or document
112-
function scrollableElement(els) {
113-
for (var i = 0, argLength = arguments.length; i < argLength; i++) {
114-
var el = arguments[i],
115-
$scrollElement = $(el);
116-
if ($scrollElement.scrollTop() > 0) {
117-
return el;
118-
} else {
119-
$scrollElement.scrollTop(1);
120-
var isScrollable = $scrollElement.scrollTop() > 0;
121-
$scrollElement.scrollTop(0);
122-
if (isScrollable) {
123-
return el;
124-
}
125-
}
126-
}
127-
return [];
128-
}
129-
130-
144+
// private function
131145
function filterPath(string) {
132146
return string
133147
.replace(/^\//,'')

0 commit comments

Comments
 (0)