forked from gregplaysguitar/ScrollBalance.js
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathjquery.scrollbalance.js
141 lines (112 loc) · 4.64 KB
/
jquery.scrollbalance.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
/*
Example usage:
$('.scrollwrap').scrollbalance({
childSelector: '.mycolumn'
});
params
childSelector:
topBuffer: the
threshold: the
*/
(function($) {
$.fn.scrollbalance = (function(options){
var settings = $.extend({
// selector to find the child elements of container which should be balanced.
childSelector: '.scrollbox',
// distance to maintain between the top of the stationary element and the top of the container.
topBuffer: 0,
// threshold for activating the plugin, eg the column heights must differ by at least this amount to be affected.
threshold: 100
}, options);
this.each(function() {
var container = $(this);
function top() {
return container.offset().top;
};
// make sure container has height
container.find(settings.childSelector).each(function() {
if (container.height() < $(this).outerHeight(true)) {
container.css('height', $(this).outerHeight(true) + 'px');
}
});
container.find(settings.childSelector).each(function() {
var col = $(this),
colHeight = col.outerHeight(true),
colWidth = col.width(),
maxScroll = container.height() - colHeight;
function pinTop() {
return (colHeight < $(window).height());
};
// don't do anything if the columns are too close in height.
if (maxScroll > settings.threshold) {
var innerHeight = col.height(),
inner = $('<div>').append(col.children());
col.html('').append(inner).css({
height: innerHeight + 'px',
position: 'relative'
});
inner.css({
width: colWidth + 'px',
position: 'absolute',
top: 0,
left: 0,
paddingLeft: col.css('paddingLeft')
});
var fixTop, fixLeft;
function balance_init() {
if (pinTop()) {
fixTop = settings.topBuffer;
}
else {
fixTop = $(window).height() - colHeight;
}
fixLeft = col.offset().left + parseInt(col.css('borderLeftWidth'));
};
function balance() {
if (pinTop()) {
var raw_scroll = $(window).scrollTop() - top() + settings.topBuffer;
}
else {
var raw_scroll = ($(window).height() + $(window).scrollTop()) - (top() + colHeight);
}
var scroll = Math.max(
0,
Math.min(
maxScroll,
raw_scroll
)
);
if (scroll && scroll < maxScroll) {
inner.css({
position: 'fixed',
top: fixTop + 'px',
left: fixLeft - $(window).scrollLeft() + 'px'
});
}
else if (scroll) {
inner.css({
position: 'absolute',
top: maxScroll + 'px',
left: 0
});
}
else {
inner.css({
position: 'absolute',
top: 0,
left: 0
});
}
};
balance_init();
balance();
$(window).scroll(balance);
$(window).resize(function() {
balance_init();
balance();
});
}
});
});
});
})(jQuery);