UNPKG

7.11 kBJavaScriptView Raw
1// PagePull 侧边栏
2var PagePull = function PagePull(container, params) {
3 /* ------------------------
4 Model
5 ------------------------ */
6 var defaults = {
7 mainClass: 'page',
8 maskClass: 'mask',
9 leftClass: 'page-side-left',
10 rightClass: 'page-side-right',
11 transition: 'push', // push | reveal
12
13 threshold: 20,
14 duration: 150,
15
16 isClickMaskHide: true,
17 drag: false
18 /*
19 Callbacks:
20 onShowedLeft:function(s)
21 onShowedRight:function(s)
22 */
23 };
24 params = params || {};
25 for (var def in defaults) {
26 if (params[def] === undefined) {
27 params[def] = defaults[def];
28 }
29 }
30 var s = this;
31 s.params = params;
32 // Container
33 s.container = typeof container === 'string' ? document.querySelector(container) : container;
34 if (!s.container) {
35 console.log('SeedsUI Error:未找到Aside的DOM对象,请检查传入参数是否正确');
36 return;
37 }
38 // Main
39 s.main = s.container.querySelector('.' + s.params.mainClass);
40 // Mask
41 s.mask = s.container.querySelector('.' + s.params.maskClass);
42 if (!s.container || !s.mask) {
43 console.log('SeedsUI Error:未找到Aside的Page,请检查传入参数是否正确');
44 return;
45 }
46 // Left 左侧栏
47 s.left = s.container.querySelector('.' + s.params.leftClass);
48 // Right 右侧栏
49 s.right = s.container.querySelector('.' + s.params.rightClass);
50 if (!s.left && !s.right) {
51 return;
52 }
53 s.target = null;
54 /* ------------------------
55 Method
56 ------------------------ */
57 s.showMask = function () {
58 s.mask.style.visibility = 'visible';
59 s.mask.style.opacity = '1';
60 };
61 s.hideMask = function () {
62 s.mask.style.visibility = 'hidden';
63 s.mask.style.opacity = '0';
64 };
65 s.show = function (direction) {
66 var target = s.target;
67 target.style.webkitTransitionDuration = s.params.duration + 'ms';
68 var x = direction === 'right' ? -s.rightClientWidth : s.leftClientWidth;
69 s.touches.posX = x;
70 target.style.webkitTransform = 'translateX(' + x + 'px)';
71 // Callback onShowedLeft | onShowedRight
72 s.target = target;
73 if (s.params.onShowedLeft || s.params.onShowedRight) {
74 setTimeout(function () {
75 if (direction === 'left' && s.params.onShowedLeft) s.params.onShowedLeft(s);
76 if (direction === 'right' && s.params.onShowedRight) s.params.onShowedRight(s);
77 }, s.params.duration);
78 }
79 };
80 s.hide = function () {
81 var target = s.target;
82 target.style.webkitTransitionDuration = s.params.duration + 'ms';
83 target.style.webkitTransform = 'translateX(0px)';
84 s.touches.posX = 0;
85 s.hideMask();
86 };
87 /* -----------------------
88 Touch Events
89 ----------------------- */
90 s.events = function (detach) {
91 var touchTarget = s.target;
92 var action = detach ? 'removeEventListener' : 'addEventListener';
93 if (s.params.drag) {
94 touchTarget[action]('touchstart', s.onTouchStart, false);
95 touchTarget[action]('touchmove', s.onTouchMove, false);
96 touchTarget[action]('touchend', s.onTouchEnd, false);
97 touchTarget[action]('touchcancel', s.onTouchEnd, false);
98 }
99 // clickMask
100 s.mask[action]('click', s.onClickMask, false);
101 };
102 // attach、dettach事件
103 s.attach = function () {
104 s.events();
105 };
106 s.detach = function () {
107 s.events(true);
108 };
109 /* -----------------------
110 Touch Handler
111 ----------------------- */
112 // Touch信息
113 s.touches = {
114 direction: 0,
115 vertical: 0,
116 horizontal: 0,
117 startX: 0,
118 startY: 0,
119 currentX: 0,
120 currentY: 0,
121 endX: 0,
122 endY: 0,
123 diffX: 0,
124 diffY: 0,
125 posX: 0
126 };
127 s.onTouchStart = function (e) {
128 e.stopPropagation();
129 // 清空滑动方向
130 s.touches.direction = 0;
131 s.touches.vertical = 0;
132 s.touches.horizontal = 0;
133 // 记录点击坐标
134 s.touches.startX = e.touches[0].clientX;
135 s.touches.startY = e.touches[0].clientY;
136 s.leftClientWidth = s.left ? s.left.clientWidth : 0;
137 s.rightClientWidth = s.right ? s.right.clientWidth : 0;
138 e.currentTarget.style.webkitTransitionDuration = '0ms';
139 };
140 s.onTouchMove = function (e) {
141 e.stopPropagation();
142 if (!s.leftClientWidth && !s.rightClientWidth) return;
143 s.touches.currentX = e.touches[0].clientX;
144 s.touches.currentY = e.touches[0].clientY;
145 s.touches.diffX = s.touches.currentX - s.touches.startX;
146 s.touches.diffY = s.touches.currentY - s.touches.startY;
147
148 // 设置滑动方向
149 if (s.touches.direction === 0) {
150 // 设置滑动方向(-1上下 | 1左右)
151 s.touches.direction = Math.abs(s.touches.diffX) > Math.abs(s.touches.diffY) ? 1 : -1;
152 }
153 if (s.touches.direction === -1) {
154 // 设置垂直方向(-1上 | 1下)
155 s.touches.vertical = s.touches.diffY < 0 ? 1 : -1;
156 }
157 if (s.touches.direction === 1) {
158 // 设置左右方向(-1左 | 1右)
159 s.touches.horizontal = s.touches.diffX < 0 ? 1 : -1;
160 }
161
162 // 如果是上下滑动则不工作
163 if (s.touches.vertical !== 0) {
164 return;
165 }
166
167 // 左滑
168 if (s.touches.diffX + s.touches.posX < -s.rightClientWidth) s.touches.diffX = -s.rightClientWidth - s.touches.posX;
169 // 右滑
170 if (s.touches.diffX + s.touches.posX > s.leftClientWidth) s.touches.diffX = s.leftClientWidth - s.touches.posX;
171
172 // 滑动
173 s.showMask();
174 e.currentTarget.style.webkitTransform = 'translateX(' + (s.touches.diffX + s.touches.posX) + 'px)';
175 };
176 s.onTouchEnd = function (e) {
177 e.stopPropagation();
178 if (s.touches.direction === -1) {
179 // 上下滑动阻止工作
180 return;
181 }
182 s.touches.endX = e.clientX || e.changedTouches[0].clientX;
183 s.touches.endY = e.clientY || e.changedTouches[0].clientY;
184 if (Math.abs(s.touches.startX - s.touches.endX) < 6 && Math.abs(s.touches.startY - s.touches.endY) < 6) {
185 // 点击
186 s.hide();
187 } else if (s.leftClientWidth || s.rightClientWidth) {
188 // 滑动
189 var direction = s.touches.diffX > 0 ? 'left' : 'right'; // 应当显示哪一边,实际left为向右滑动,right反之
190 if (Math.abs(s.touches.diffX) > s.params.threshold) {
191 // 如果左侧展开,并且向左滑动,则隐藏
192 if (s.touches.posX > 0 && direction === 'right') {
193 s.hide();
194 // 如果右侧展开,并且向右滑动,则隐藏
195 } else if (s.touches.posX < 0 && direction === 'left') {
196 s.hide();
197 } else {
198 s.show(direction);
199 }
200 } else {
201 if (s.touches.posX !== 0) {
202 s.show(s.touches.posX > 0 ? 'left' : 'right');
203 } else {
204 s.hide();
205 }
206 }
207 }
208 };
209 s.onClickMask = function (e) {
210 s.target = e.target;
211 if (s.params.onClickMask) s.params.onClickMask(s);
212 if (s.params.isClickMaskHide) {
213 s.hide();
214 }
215 e.stopPropagation();
216 };
217 /* -----------------------
218 Init
219 ----------------------- */
220 s.update = function () {
221 if (s.target) {
222 s.detach();
223 }
224 if (this.params.transition === 'reveal') {
225 s.target = s.main;
226 } else {
227 s.target = s.container;
228 }
229 s.attach();
230 };
231 s.update();
232};
233
234export default PagePull;
\No newline at end of file