移动端的picker参考vux

参考vux移动端的ui组件,做了一个picker,测试在微信,uc主流浏览器能够正常工作。而在华为浏览器根本不能使用。而测试了vux的原有picker组件,发现在华为自带浏览器中,效果依然能够实现。

这时明白,原来vux也并非想的那么简单,兼容性这块做的很不错。或者是因为采用了vue的缘故?

实现代码如下:

  1 <!DOCTYPE html>
  2 <html lang="en">
  3 
  4 <head>
  5     <meta charset="UTF-8">
  6     <title>制作移动端的picker参考vux</title>
  7     <meta name="viewport" content="width=device-width,initial-scale=1.0">
  8     <style type="text/css">
  9     * {
 10         margin: 0;
 11         padding: 0;
 12     }
 13 
 14 
 15     .content {
 16         position: absolute;
 17         bottom: 0;
 18         height: 40%;
 19         background: #fff;
 20         width: 100%;
 21         overflow: hidden;
 22         display: none;
 23         z-index: 9999
 24     }
 25 
 26     .title {
 27         display: flex;
 28         justify-content: center;
 29         background-color: #fbf9fe;
 30     }
 31 
 32     .title div {
 33         height: 44px;
 34         display: flex;
 35         justify-content: center;
 36         padding-left: 10px;
 37         padding-right: 10px;
 38     }
 39 
 40     .tip {
 41         flex: 1;
 42         align-items: center;
 43     }
 44 
 45     .cancel,
 46     .finish {
 47         width: 40px;
 48         align-items: center;
 49     }
 50 
 51     .cancel {
 52         color: #828282;
 53     }
 54 
 55     .finish {
 56 
 57         color: #FF9900;
 58     }
 59 
 60     .dataBox {
 61         position: relative;
 62         border-top: 1px solid #f1f2f3;
 63         display: flex;
 64         height: 100%;
 65         background: #f1f2f3;
 66         overflow: hidden;
 67         height: 170px;
 68     }
 69 
 70     .middle {
 71         position: absolute;
 72         width: 100%;
 73         height: 34px;
 74         left: 0;
 75         top: 68px;
 76         z-index: 3;
 77         background-image: linear-gradient(to bottom, #d0d0d0, #d0d0d0, transparent, transparent), linear-gradient(to top, #d0d0d0, #d0d0d0, transparent, transparent);
 78         background-position: top, bottom;
 79         background-size: 100% 1px;
 80         background-repeat: no-repeat;
 81     }
 82 
 83     .mengban {
 84         position: absolute;
 85         left: 0;
 86         top: 0;
 87         height: 100%;
 88         margin: 0 auto;
 89         width: 100%;
 90         z-index: 3;
 91         transform: translateZ(0px);
 92         background-image: -webkit-linear-gradient(top, rgba(255, 255, 255, 0.95), rgba(255, 255, 255, 0.6)), -webkit-linear-gradient(bottom, rgba(255, 255, 255, 0.95), rgba(255, 255, 255, 0.6));
 93         background-image: linear-gradient(to bottom, rgba(255, 255, 255, 0.95), rgba(255, 255, 255, 0.6)), linear-gradient(to top, rgba(255, 255, 255, 0.95), rgba(255, 255, 255, 0.6));
 94         background-position: top, bottom;
 95         background-size: 100% 68px;
 96         background-repeat: no-repeat;
 97     }
 98 
 99     .data {
100         position: absolute;
101         left: 0;
102         top: 0;
103         width: 100%;
104         z-index: 1;
105         webkit-transform: translateZ(0);
106         -moz-transform: translateZ(0);
107         -ms-transform: translateZ(0);
108         -o-transform: translateZ(0);
109         transform: translateZ(0);
110     }
111 
112     .data div {
113         text-align: center;
114         font-size: 16px;
115         height: 34px;
116         line-height: 34px;
117         color: #000;
118     }
119 
120 
121     .active {
122         color: red !important;
123     }
124 
125     @-webkit-keyframes fadeInUp {
126         from {
127             opacity: 0;
128             -webkit-transform: translate3d(0, 100%, 0);
129             transform: translate3d(0, 100%, 0);
130         }
131 
132         to {
133             opacity: 1;
134             -webkit-transform: translate3d(0, 0, 0);
135             transform: translate3d(0, 0, 0);
136         }
137     }
138 
139     @keyframes fadeInUp {
140         from {
141             opacity: 0;
142             -webkit-transform: translate3d(0, 100%, 0);
143             transform: translate3d(0, 100%, 0);
144         }
145 
146         to {
147             opacity: 1;
148             -webkit-transform: translate3d(0, 0, 0);
149             transform: translate3d(0, 0, 0);
150         }
151     }
152 
153     .fadeInUp {
154         -webkit-animation-name: fadeInUp;
155         animation-name: fadeInUp;
156     }
157 
158     .animated {
159         -webkit-animation-duration: 1s;
160         animation-duration: 1s;
161         -webkit-animation-fill-mode: both;
162         animation-fill-mode: both;
163     }
164 
165     @-webkit-keyframes fadeIn {
166         from {
167             opacity: 0;
168         }
169 
170         to {
171             opacity: 1;
172         }
173     }
174 
175     @keyframes fadeIn {
176         from {
177             opacity: 0;
178         }
179 
180         to {
181             opacity: 1;
182         }
183     }
184 
185     .fadeIn {
186         -webkit-animation-name: fadeIn;
187         animation-name: fadeIn;
188     }
189 
190     @-webkit-keyframes fadeOut {
191         from {
192             opacity: 1;
193         }
194 
195         to {
196             opacity: 0;
197             display: none;
198         }
199     }
200 
201     @keyframes fadeOut {
202         from {
203             opacity: 1;
204         }
205 
206         to {
207             opacity: 0;
208         }
209     }
210 
211     .fadeOut {
212         -webkit-animation-name: fadeOut;
213         animation-name: fadeOut;
214     }
215 
216     @-webkit-keyframes fadeInDown {
217         from {
218             opacity: 0;
219             -webkit-transform: translate3d(0, -100%, 0);
220             transform: translate3d(0, -100%, 0);
221         }
222 
223         to {
224             opacity: 1;
225             -webkit-transform: translate3d(0, 0, 0);
226             transform: translate3d(0, 0, 0);
227         }
228     }
229 
230     @keyframes fadeInDown {
231         from {
232             opacity: 0;
233             -webkit-transform: translate3d(0, -100%, 0);
234             transform: translate3d(0, -100%, 0);
235         }
236 
237         to {
238             opacity: 1;
239             -webkit-transform: translate3d(0, 0, 0);
240             transform: translate3d(0, 0, 0);
241         }
242     }
243 
244     .fadeInDown {
245         -webkit-animation-name: fadeInDown;
246         animation-name: fadeInDown;
247     }
248 
249     .mask {
250         display: none;
251         position: fixed;
252         top: 0;
253         bottom: 0;
254         left: 0;
255         right: 0;
256         z-index: 1;
257         background-color: rgba(0, 0, 0, 0.5);
258     }
259 
260     @-webkit-keyframes fadeOutDown {
261         from {
262             opacity: 1;
263         }
264 
265         to {
266             opacity: 0;
267             -webkit-transform: translate3d(0, 100%, 0);
268             transform: translate3d(0, 100%, 0);
269         }
270     }
271 
272     @keyframes fadeOutDown {
273         from {
274             opacity: 1;
275         }
276 
277         to {
278             opacity: 0;
279             -webkit-transform: translate3d(0, 100%, 0);
280             transform: translate3d(0, 100%, 0);
281         }
282     }
283 
284     .fadeOutDown {
285         -webkit-animation-name: fadeOutDown;
286         animation-name: fadeOutDown;
287     }
288     </style>
289 </head>
290 
291 <body>
292     <button id="test">弹出</button>
293     <div class="content animated">
294         <div class="title">
295             <div class="cancel">取消</div>
296             <div class="tip">请选择</div>
297             <div class="finish" id="finish">完成</div>
298         </div>
299         <div class="dataBox" id="dataBox">
300             <div class="middle"></div>
301             <div class="mengban"></div>
302             <div class="data" id="data">
303                 <div class="active">这是数据1</div>
304                 <div>这是数据2</div>
305                 <div>这是数据3</div>
306                 <div>这是数据4</div>
307                 <div>这是数据2</div>
308                 <div>这是数据3</div>
309                 <div>这是数据4</div>
310                 <div>这是数据3</div>
311                 <div>这是数据4</div>
312                 <div>这是数据2</div>
313                 <div>这是数据3</div>
314                 <div>这是数据4</div>
315             </div>
316         </div>
317     </div>
318     <div class="mask animated"></div>
319     <script type="text/javascript">
320     //写成标准的组件形式
321     (function(window, document) {
322         //兼容性处理
323         function whichAnimationEvent() {
324             var t,
325                 el = document.createElement("fakeelement");
326 
327             var animations = {
328                 "animation": "animationend",
329                 "OAnimation": "oAnimationEnd",
330                 "msAnimation":"msAnimationEnd",
331                 "WebkitAnimation": "webkitAnimationEnd"
332             }
333 
334             for (t in animations) {
335                 if (el.style[t] !== undefined) {
336                     return animations[t];
337                 }
338             }
339         }
340         //兼容性的过度结束事件
341         var animationEndEvent = whichAnimationEvent();
342 
343 
344         //transform兼容
345         function whichTransform() {
346             var el = document.createElement("fakeelement");
347             var transforms = ["webkitTransform", "msTransform", "OTransform", "transform"];
348 
349             for (var t in transforms) {
350                 if (el.style[transforms[t]] !== undefined) {
351                     return transforms[t];
352                 }
353             }
354         }
355 
356          //transition兼容性处理
357         function whichTransition() {
358             var el = document.createElement("fakeelement");
359             var transitions = ["transition", "OTransition", "WebkitTransition", "msTransition"];
360 
361             for (var t in transitions) {
362                 if (el.style[transitions[t]] !== undefined) {
363                     return transitions[t];
364                 }
365             }
366         }
367         //测试触发
368         var test = document.querySelector("#test");
369         var content = document.querySelector(".content"),
370             mask = document.querySelector(".mask"),
371             INITL = 68;
372 
373         test.addEventListener("click", function() {
374      
375             content.style.display = "block";
376             mask.style.display = "block";
377             content.classList.remove("fadeOutDown");
378             content.classList.add("fadeInUp");
379             mask.classList.remove("fadeOut");
380             mask.classList.add("fadeIn");
381 
382         })
383 
384         //避免默认事件
385         document.addEventListener('touchmove', function(e) {
386             e.preventDefault();
387         }, { passive: false });
388 
389         var box = document.getElementById('dataBox'),
390             data = document.getElementById("data"),
391             startY = 0,
392             endY = 0,
393             transformX = 0,
394             h = parseInt(window.getComputedStyle(document.getElementById("data").children[0], false).height),
395             n = document.getElementById("data").children.length;
396 
397 
398         //初始化高度
399         function init(y) {
400             data.style = `transform: translate3d(0px, ${y}px, 0px)`;
401         }
402         init(INITL);
403 
404         //开始滑动
405         box.addEventListener("touchstart", function(e) {
406             console.log(data.style.transform);
407             startY = e.touches[0].pageY;
408             transformX = data.style.transform.match(/translate3d\((-?\d+)px,\s*(-?\d+)px,\s*(\d+)px\)/i)[2] ? data.style.transform.match(/translate3d\((-?\d+)px,\s*(-?\d+)px,\s*(\d+)px\)/i)[2] : 0;
409 
410         });
411         //滑动
412         box.addEventListener("touchmove", function(e) {
413 
414             var offsetY = e.touches[0].pageY - startY;
415             data.style[whichTransform()] = `translate3d(0,${parseInt(offsetY)+parseInt(transformX)}px,0)`;
416             data.style[whichTransition()] = '100ms ease-out';
417 
418         })
419         //结束滑动
420         box.addEventListener("touchend", function(e) {
421             transformX = data.style.transform.match(/translate3d\((-?\d+)px,\s*(-?\d+)px,\s*(\d+)px\)/i)[2] ? data.style.transform.match(/translate3d\((-?\d+)px,\s*(-?\d+)px,\s*(-?\d+)px\)/i)[2] : 0;
422 
423             if (transformX > INITL) {
424                 transformX = INITL;
425             }
426 
427             if (transformX < -(n - Math.round(INITL / h) - 1) * h) {
428                 transformX = -(n - Math.round(INITL / h) - 1) * h;
429             }
430             var dis = Math.round(transformX / h) * h;
431 
432             data.style[whichTransform()] = `translate3d(0,${dis}px,0)`;
433             data.style[whichTransition()] = '300ms ease-out';
434             [].slice.apply(data.children).forEach(function(val, index) {
435                 val.classList.remove("active");
436             })
437 
438             data.children[Math.round(Math.abs(transformX - INITL) / h)].classList.add("active");
439 
440         })
441 
442         var finish = document.getElementById("finish");
443         var cancel = document.querySelector(".cancel");
444 
445         //点击完成
446         finish.addEventListener("click", function() {
447             alert(data.querySelector(".active").innerHTML);
448         })
449 
450         //点击取消
451         cancel.addEventListener("click", function() {
452 
453             content.classList.remove("fadeInUp");
454             content.classList.add("fadeOutDown");
455             mask.classList.remove("fadeIn");
456             mask.classList.add("fadeOut");
457 
458         })
459 
460         //从block到none的过渡处理
461         content.addEventListener(animationEndEvent, function() {
462             if (content.classList.contains('fadeOutDown')) {
463                 content.style.display = "none";
464             }
465         });
466         mask.addEventListener(animationEndEvent, function() {
467             if (mask.classList.contains('fadeOut')) {
468                 mask.style.display = "none";
469             }
470         });
471     })(window, document);
472     </script>
473 </body>
474 
475 </html>

滑动这块采用的是touch事件;

过渡效果利用的是css3的animation.css文件;

利用了一个以前没有应用的api:animationend,用来监控animation是否结束,结束后发生回调。

其它利用classlist对类进行增删。

做了一下兼容下,transform和transition的兼容性。

后面需要优化一下。

猜你喜欢

转载自www.cnblogs.com/zhensg123/p/9289337.html