-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathjquery.scrollable-sticky.js
122 lines (110 loc) · 4.02 KB
/
jquery.scrollable-sticky.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
/*
* jQuery Scrollable Sticky - v0.1.0
* A jQuery plugin which enables fixed positioned elements, that are higher than the viewport, to be scrolled.
* https://github.com/egeriis/jquery-scrollable-sticky/
*
* Made by Ronni Egeriis Persson
* Under MIT License
*/
;(function($, window, document, undefined) {
var pluginName = 'scrollableSticky',
defaults = {
offset: 0
};
function Plugin(el, options) {
this.el = el;
this.$el = $(el);
this.settings = $.extend({}, defaults, options);
this._defaults = defaults;
this._name = pluginName;
this.init();
}
Plugin.prototype = {
init: function()
{
this.offset = this.$el.offset();
this.parentsOffset = this.$el.offsetParent().offset();
this.offsetParent = {
top: this.offset.top - this.parentsOffset.top,
left: this.offset.left - this.parentsOffset.left
};
this.dimensions = {
width: this.$el.width(),
height: this.$el.height()
};
this.scrollTop = 0;
this.adjustmentStart = 0;
$(window).scroll($.proxy(this.onScroll, this));
this.placeElement();
},
placeElement: function()
{
this.$el
.css({
position: 'absolute',
top: this.offsetParent.top,
left: this.offsetParent.left,
width: this.dimensions.width
});
},
placeElementFixed: function(top)
{
this.$el
.css({
position: 'fixed',
top: top || this.offset.top,
left: this.offset.left
});
},
onScroll: function()
{
var windowHeight = $(window).height(),
scrollTop = $(window).scrollTop();
if (windowHeight > this.dimensions.height) {
return this.placeElementFixed();
}
// adjustmentHeight is the scrollable height of our element
var adjustmentHeight = this.dimensions.height - windowHeight + this.offset.top + this.settings.offset,
adjustment = 0;
// If adjustmentStart is specified, user has started scrolling backwards
if (this.adjustmentStart > 0) {
// adjustment is a calculation of the bottom offset for our element
adjustment = this.adjustmentStart - scrollTop;
// When adjustment reaches zero the user has reached the top
if (adjustment < 0) {
// Reset adjustmentStart
this.adjustmentStart = 0;
} else if (adjustment > adjustmentHeight) {
this.adjustmentStart = scrollTop + adjustmentHeight;
}
// If a user is scrolling backwards we set adjustmentStart
} else if (scrollTop < this.scrollTop) {
this.adjustmentStart = scrollTop;
}
// If are about to scroll beyond the bottom of the element
// it should be fixed to the bottom of the browser window
if (scrollTop > adjustmentHeight - adjustment)
{
var top = adjustmentHeight * -1 + this.offset.top;
if (adjustment >= 0) {
top += Math.min(adjustment, adjustmentHeight);
}
this.placeElementFixed(top);
}
else
{
this.adjustmentStart = 0;
this.placeElement();
}
this.scrollTop = scrollTop;
}
};
$.fn[pluginName] = function(options) {
this.each(function() {
if ( ! $.data(this, 'plugin_' + pluginName)) {
$.data(this, 'plugin_' + pluginName, new Plugin(this, options));
}
});
return this;
};
})(jQuery, window, document);