sticky.js
2.1 KB
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
/**
* Makes element sticky to the top of the window (offset by pixels specified in sticky-offset) when page is scolled to or bellow the element.
*/
export default function () {
return {
restrict: 'A',
link: function ($scope, $elem, $attrs) {
var offsetTop = $attrs.stickyOffset || 0,
$window = angular.element(window),
stickyLine = $elem.offset().top,
scrollTop,
state = 'free';
// Run this on every scroll.
function onScroll(e) {
// Get scroll position.
scrollTop = $window.scrollTop();
// Check if the window has passed the sticky line.
if (state == 'free' && scrollTop > stickyLine - offsetTop) {
// Scroll bellow browser chrome.
if ($(document).height() - $window.height() <= scrollTop) {
return;
}
if (!$elem.next('.sticky-dummy')[0]) {
$elem.after($('<div>').addClass('sticky-dummy').height($elem.outerHeight()));
}
$elem.addClass('sticky');
state = 'fixed';
} else if (state == 'fixed' && scrollTop < stickyLine - offsetTop) {
$elem.removeClass('sticky');
$elem.next('.sticky-dummy').remove();
state = 'free';
}
}
// Attach scroll and resize listeners.
$window.on('scroll', onScroll);
// Watch height of the element so that we can adjust dummy height too.
$scope.$watch(
function () {
return $elem.outerHeight();
},
function (newValue, oldValue) {
if (newValue != oldValue) {
if ($elem.next('.sticky-dummy')[0]) {
$elem.next('.sticky-dummy').height($elem.outerHeight());
}
}
}
);
},
};
}