-
Notifications
You must be signed in to change notification settings - Fork 24
/
Copy pathion-sticky.js
85 lines (78 loc) · 4.17 KB
/
ion-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
angular.module('ion-sticky', ['ionic'])
.directive('ionSticky', ['$ionicPosition', '$compile', '$timeout', function ($ionicPosition, $compile, $timeout) {
return {
restrict: 'A',
require: '^$ionicScroll',
link: function ($scope, $element, $attr, $ionicScroll) {
var scroll = angular.element($ionicScroll.element);
var clone;
var cloneVal = function(original, to) {
var my_textareas = original.getElementsByTagName('textarea');
var result_textareas = to.getElementsByTagName('textarea');
var my_selects = original.getElementsByTagName('select');
var result_selects = to.getElementsByTagName('select');
for (var i = 0, l = my_textareas.length; i < l; ++i)
result_textareas[i].value = my_textareas[i].value;
for (var i = 0, l = my_selects.length; i < l; ++i)
result_selects[i].value = my_selects[i].value;
};
// creates the sticky divider clone and adds it to DOM
var createStickyClone = function ($element) {
clone = $element.clone().css({
position: 'absolute',
top: $ionicPosition.position(scroll).top + "px", // put to top
left: 0,
right: 0
});
$attr.ionStickyClass = ($attr.ionStickyClass) ? $attr.ionStickyClass : 'assertive';
cloneVal($element[0], clone[0]);
clone[0].className += ' ' + $attr.ionStickyClass;
clone.removeAttr('ng-repeat-start').removeAttr('ng-if');
scroll.parent().append(clone);
// compile the clone so that anything in it is in Angular lifecycle.
$compile(clone)($scope);
$scope.$apply();
};
var removeStickyClone = function () {
if (clone)
clone.remove();
clone = null;
};
$scope.$on("$destroy", function () {
// remove the clone and unbind the scroll listener
removeStickyClone();
angular.element($ionicScroll.element).off('scroll');
});
var lastActive;
var updateSticky = ionic.throttle(function() {
var divHeight = $ionicPosition.offset($element[0].getElementsByClassName($attr.ionSticky || "item-divider")).height;
//console.log(performance.now());
var active = null;
var dividers = [];
var tmp = $element[0].getElementsByClassName($attr.ionSticky || "item-divider");
for (var i = 0; i < tmp.length; ++i) {
dividers.push(angular.element(tmp[i]));
}
for (var i = 0; i < dividers.length; ++i) { // can be changed to binary search
if ($ionicPosition.offset(dividers[i]).top - $ionicPosition.offset($element).top - divHeight < 0) { // this equals to jquery outerHeight
if (i === dividers.length-1 || $ionicPosition.offset(dividers[i+1]).top -
($ionicPosition.offset($element).top + dividers[i+1].prop('offsetHeight')) + divHeight > 0) { //when clone covers new header
active = dividers[i][0];
break;
}
}
}
if (lastActive != active) {
removeStickyClone();
lastActive = active;
if (active != null)
createStickyClone(angular.element(active));
}
//console.log(performance.now());
}, 200);
scroll.on('scroll', function (event) {
updateSticky();
});
}
}
}]);