forked from Khan/khan-exercises
/
jquery.adhesion.js
125 lines (97 loc) · 2.66 KB
/
jquery.adhesion.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
(function() {
jQuery.fn.adhere = function( options ) {
options = jQuery.extend( {
container: null,
topMargin: 0,
bottomMargin: 0
}, options );
var container = jQuery( options.container ).eq( 0 );
jQuery( this ).each( function() {
var el = jQuery( this );
var data = el.data( "adhesion" );
var updateDimensions = ( data != null );
if ( data == null ) {
data = {};
el.data( "adhesion", data );
}
var shim = data.shim != null ? data.shim : jQuery( "<div>" );
shim.css( {
margin: 0,
padding: 0,
border: 0
} );
if ( updateDimensions ) {
if ( data.scrollHandler != null ) {
data.scrollHandler();
}
return;
}
el.before( shim );
el.parent().css( "position", "relative" );
var state = "unstuck";
var height;
var stick = function( update ) {
if ( state === "stuck" && update !== true ) return;
shim.height( height );
el.parent().height( "auto" );
el.css( {
position: "fixed",
top: options.topMargin,
bottom: "auto",
left: el.parent().offset().left,
width: shim.width()
} );
state = "stuck";
};
var unstick = function() {
if ( state === "unstuck" ) return;
shim.height( 0 );
el.parent().height( "auto" );
el.css( {
position: "static",
width: "auto"
} );
state = "unstuck";
};
var bottom = function() {
if ( state === "bottom" ) return;
shim.height( 0 );
el.parent().height( container.height() );
el.css( {
position: "absolute",
top: "auto",
bottom: 0,
left: "auto",
width: shim.width()
} );
state = "bottom";
};
var scrollHandler = function( update ) {
var scrollTop = jQuery( window ).scrollTop();
var windowHeight = jQuery( window ).height();
var containerOffset = container.offset();
var containerHeight = container.outerHeight();
height = el.outerHeight( true );
var containerScrolledTop = containerOffset.top - scrollTop;
var containerScrolledBottom = containerScrolledTop + containerHeight;
var elFixedBottom = height + options.topMargin + options.bottomMargin;
var shimRight = shim.offset().left + shim.outerWidth();
if ( elFixedBottom < windowHeight && containerScrolledTop - options.topMargin < 0 && shimRight <= jQuery( window ).width() ) {
if ( elFixedBottom < containerScrolledBottom ) {
stick( update );
} else {
bottom();
}
} else {
unstick();
}
};
var resizeHandler = function() {
scrollHandler( true );
};
data.scrollHandler = scrollHandler;
jQuery( window ).scroll( scrollHandler );
jQuery( window ).resize( resizeHandler );
} );
};
})();