-
Notifications
You must be signed in to change notification settings - Fork 28
/
Copy pathsidebar-follow-jquery.js
112 lines (95 loc) · 2.99 KB
/
sidebar-follow-jquery.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
/**
* @author: mg12 [http://www.neoease.com/]
* @update: 2012/12/05
*/
SidebarFollow = function() {
this.config = {
element: null, // 处理的节点
distanceToTop: 0 // 节点上边到页面顶部的距离
};
this.cache = {
originalToTop: 0, // 原本到页面顶部的距离
prevElement: null, // 上一个节点
parentToTop: 0, // 父节点的上边到顶部距离
placeholder: jQuery('<div>') // 占位节点
}
};
SidebarFollow.prototype = {
init: function(config) {
this.config = config || this.config;
var _self = this;
var element = jQuery(_self.config.element);
// 如果没有找到节点, 不进行处理
if(element.length <= 0) {
return;
}
// 获取上一个节点
var prevElement = element.prev();
while(prevElement.is(':hidden')) {
prevElement = prevElement.prev();
if(prevElement.length <= 0) {
break;
}
}
_self.cache.prevElement = prevElement;
// 计算父节点的上边到顶部距离
var parent = element.parent();
var parentToTop = parent.offset().top;
var parentBorderTop = parent.css('border-top');
var parentPaddingTop = parent.css('padding-top');
_self.cache.parentToTop = parentToTop + parentBorderTop + parentPaddingTop;
// 滚动屏幕
jQuery(window).scroll(function() {
_self._scrollScreen({element:element, _self:_self});
});
// 改变屏幕尺寸
jQuery(window).resize(function() {
_self._scrollScreen({element:element, _self:_self});
});
},
/**
* 修改节点位置
*/
_scrollScreen: function(args) {
var _self = args._self;
var element = args.element;
var prevElement = _self.cache.prevElement;
// 获得到顶部的距离
var toTop = _self.config.distanceToTop;
// 如果 body 有 top 属性, 消除这些位移
var bodyToTop = parseInt(jQuery('body').css('top'), 10);
if(!isNaN(bodyToTop)) {
toTop += bodyToTop;
}
// 获得到顶部的绝对距离
var elementToTop = element.offset().top - toTop;
// 如果存在上一个节点, 获得到上一个节点的距离; 否则计算到父节点顶部的距离
var referenceToTop = 0;
if(prevElement && prevElement.length === 1) {
referenceToTop = prevElement.offset().top + prevElement.outerHeight();
} else {
referenceToTop = _self.cache.parentToTop - toTop;
}
// 当节点进入跟随区域, 跟随滚动
if(jQuery(document).scrollTop() > elementToTop) {
// 添加占位节点
var elementHeight = element.outerHeight();
_self.cache.placeholder.css('height', elementHeight).insertBefore(element);
// 记录原位置
_self.cache.originalToTop = elementToTop;
// 修改样式
element.css({
top: toTop + 'px',
position: 'fixed'
});
// 否则回到原位
} else if(_self.cache.originalToTop > elementToTop || referenceToTop > elementToTop) {
// 删除占位节点
_self.cache.placeholder.remove();
// 修改样式
element.css({
position: 'static'
});
}
}
};