UNPKG

5.88 kBJavaScriptView Raw
1// ListPull 列表滑动菜单
2var ListPull = function ListPull(container, params) {
3 /* -----------------------
4 Model
5 ----------------------- */
6 var defaults = {
7 leftClass: 'list-pull-left',
8 rightClass: 'list-pull-right',
9 handlerClass: 'list-pull-handler',
10 activeClass: 'active',
11 threshold: 20,
12 duration: 150
13 /*
14 Callbacks:
15 onClick:function(s)
16 onPull:function(s)
17 onShowedLeft:function(s)
18 onShowedRight:function(s)
19 */
20 };
21 params = params || {};
22 for (var def in defaults) {
23 if (params[def] === undefined) {
24 params[def] = defaults[def];
25 }
26 }
27 var s = this;
28 // Params
29 s.params = params;
30 // Container
31 s.container = typeof container === 'string' ? document.querySelector(container) : container;
32 if (!s.container) {
33 console.log('SeedsUI Error:未找到ListPull的DOM对象,请检查传入参数是否正确');
34 return;
35 }
36 /* -----------------------
37 Method
38 ----------------------- */
39 s.hide = function (target) {
40 if (!target) {
41 var actives = s.container.querySelectorAll('.' + s.params.activeClass);
42 if (actives.length > 0) target = actives[0];
43 }
44 if (target) {
45 target.style.webkitTransitionDuration = s.params.duration + 'ms';
46 target.style.webkitTransform = 'translate3d(0px,0px,0px)';
47 target.classList.remove(s.params.activeClass);
48 }
49 };
50 s.show = function (target, direction) {
51 target.style.webkitTransitionDuration = s.params.duration + 'ms';
52 var x = direction === 'right' ? -s.rightClientWidth : s.leftClientWidth;
53 target.style.webkitTransform = 'translate3d(' + x + 'px,0px,0px)';
54 target.classList.add(s.params.activeClass);
55 // Callback onShowedLeft | onShowedRight
56 s.target = target;
57 if (s.params.onShowedLeft || s.params.onShowedRight) {
58 setTimeout(function () {
59 if (direction === 'left' && s.params.onShowedLeft) s.params.onShowedLeft(s);
60 if (direction === 'right' && s.params.onShowedRight) s.params.onShowedRight(s);
61 }, s.params.duration);
62 }
63 };
64 /* -----------------------
65 Touch Events
66 ----------------------- */
67 s.events = function (detach) {
68 var touchTarget = s.container;
69 var action = detach ? 'removeEventListener' : 'addEventListener';
70 touchTarget[action]('touchstart', s.onTouchStart, false);
71 touchTarget[action]('touchmove', s.onTouchMove, false);
72 touchTarget[action]('touchend', s.onTouchEnd, false);
73 touchTarget[action]('touchcancel', s.onTouchEnd, false);
74 };
75 s.attach = function (event) {
76 s.events();
77 };
78 s.detach = function (event) {
79 s.events(true);
80 };
81 /* -----------------------
82 Touch Handler
83 ----------------------- */
84 // Touch信息
85 s.touches = {
86 direction: 0,
87 vertical: 0,
88 horizontal: 0,
89 startX: 0,
90 startY: 0,
91 currentX: 0,
92 currentY: 0,
93 endX: 0,
94 endY: 0,
95 diffX: 0,
96 diffY: 0
97 // 索引
98 };s.activeIndex = 0;
99
100 s.onTouchStart = function (e) {
101 e.stopPropagation();
102 // 清空滑动方向
103 s.touches.direction = 0;
104 s.touches.vertical = 0;
105 s.touches.horizontal = 0;
106 // 记录点击坐标
107 s.touches.startX = e.touches[0].clientX;
108 s.touches.startY = e.touches[0].clientY;
109 s.leftClientWidth = 0;
110 s.rightClientWidth = 0;
111 // 如果点击时有展开的列表项,则先收缩
112 var actives = s.container.querySelectorAll('.' + s.params.activeClass);
113 if (actives.length > 0) {
114 s.hide(actives[0]);
115 } else if (e.target.classList.contains(s.params.handlerClass)) {
116 // 拉动对象
117 var left = e.target.parentNode.querySelector('.' + s.params.leftClass);
118 var right = e.target.parentNode.querySelector('.' + s.params.rightClass);
119 s.leftClientWidth = left ? left.clientWidth : 0;
120 s.rightClientWidth = right ? right.clientWidth : 0;
121 }
122 };
123 s.onTouchMove = function (e) {
124 e.stopPropagation();
125 if (!s.leftClientWidth && !s.rightClientWidth) return;
126 s.touches.currentX = e.touches[0].clientX;
127 s.touches.currentY = e.touches[0].clientY;
128 s.touches.diffX = s.touches.currentX - s.touches.startX;
129 s.touches.diffY = s.touches.currentY - s.touches.startY;
130
131 // 设置滑动方向
132 if (s.touches.direction === 0) {
133 // 设置滑动方向(-1上下 | 1左右)
134 s.touches.direction = Math.abs(s.touches.diffX) > Math.abs(s.touches.diffY) ? 1 : -1;
135 }
136 if (s.touches.direction === -1) {
137 // 设置垂直方向(-1上 | 1下)
138 s.touches.vertical = s.touches.diffY < 0 ? 1 : -1;
139 }
140 if (s.touches.direction === 1) {
141 // 设置左右方向(-1左 | 1右)
142 s.touches.horizontal = s.touches.diffX < 0 ? 1 : -1;
143 }
144
145 // 如果是上下滑动则不工作
146 if (s.touches.vertical !== 0) {
147 return;
148 }
149
150 if (s.touches.diffX < -s.rightClientWidth) s.touches.diffX = -s.rightClientWidth;
151 if (s.touches.diffX > s.leftClientWidth) s.touches.diffX = s.leftClientWidth;
152
153 // Callback onPull
154 if (s.params.onPull) s.params.onPull(s);
155
156 // 滑动
157 e.target.style.webkitTransform = 'translate3d(' + s.touches.diffX + 'px,0px,0px)';
158 };
159 s.onTouchEnd = function (e) {
160 e.stopPropagation();
161 if (s.touches.direction === -1) {
162 // 上下滑动阻止工作
163 return;
164 }
165 s.touches.endX = e.clientX || e.changedTouches[0].clientX;
166 s.touches.endY = e.clientY || e.changedTouches[0].clientY;
167 if (Math.abs(s.touches.startX - s.touches.endX) < 6 && Math.abs(s.touches.startY - s.touches.endY) < 6) {
168 // 点击
169 s.target = e.target;
170 s.hide(e.target);
171 // 在展开状态下(s.leftClientWidth || s.rightClientWidth),如果点击主容器handler将无效
172 if (!e.target.classList.contains(s.params.handlerClass) || s.leftClientWidth || s.rightClientWidth) {
173 // Callback onClick
174 if (s.params.onClick) s.params.onClick(s);
175 }
176 } else if (s.leftClientWidth || s.rightClientWidth) {
177 // 滑动
178 if (Math.abs(s.touches.diffX) > s.params.threshold) {
179 s.show(e.target, s.touches.diffX > 0 ? 'left' : 'right');
180 } else {
181 s.hide(e.target);
182 }
183 }
184 };
185 // Init
186 s.init = function () {
187 s.attach();
188 };
189 s.init();
190};
191
192export default ListPull;
\No newline at end of file