fix-nav.js
3.71 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
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
/**
* make the nav (or any element) to be fixed on top
* author: Bill.Zhao
* repository: https://github.com/buildAll/fix-nav.js/blob/master/fix-nav.js
* license: MIT
*/
let $ = require('yoho-jquery');
(function() {
$.fn.fixNav = function(options) {
let defaults = {
autoRollTop: false, // make the content below the fixed el roll to top when the el is clicked
zIndex: 999 // the z-index when the element is fixed
};
let settings = $.extend({}, defaults, options || {});
let scrollDirection = {
direction: '',
preScrollTop: 0,
curScrollTop: 0,
getDirection: function() {
this.curScrollTop = $(window).scrollTop();
this.curScrollTop < this.preScrollTop ?
this.direction = 'up' :
this.direction = 'down';
this.preScrollTop = this.curScrollTop;
},
isUp: function() {
this.getDirection();
return this.direction === 'up';
},
isDown: function() {
this.getDirection();
return this.direction === 'down';
}
};
let utils = {
lock: false,
rollTo: function(el, toWhere) {
$(el).click(function() {
if ($(this).css('position') === 'fixed') {
utils.lock = true;
$('body').animate({
scrollTop: toWhere
}, 100);
setTimeout(function() {
utils.lock = false;
}, 500);
}
});
}
};
let styleCtrl = {
isSet: false,
preStyle: '',
preTop: null,
$el: null,
setFix: function(el, originTop) {
if (!this.isSet) {
this.$el = $(el);
this.preStyle = this.$el.attr('style');
this.preTop = originTop;
utils.lock = true;
this.$el.css({
position: 'fixed',
top: 0,
'z-index': settings.zIndex
});
this.isSet = true;
setTimeout(function() {
utils.lock = false;
}, 500);
if (settings.autoRollTop) {
utils.rollTo(this.$el.get(0), originTop);
}
}
},
clearFix: function() {
let windowTop;
if (this.$el) {
windowTop = $(window).scrollTop();
if (windowTop <= this.preTop) {
if (this.preStyle) {
this.$el.attr('style', this.preStyle);
} else {
this.$el.removeAttr('style');
}
this.isSet = false;
}
}
}
};
return this.each(function(index, el) {
let originPoistion = $(el).offset().top;
$(window).scroll(function() {
if (utils.lock) {
return;
}
let elementTop = originPoistion - $(window).scrollTop();
if (scrollDirection.isDown() && elementTop <= 0) {
styleCtrl.setFix(el, originPoistion);
} else {
styleCtrl.clearFix();
}
});
});
};
}());