移动端的picker参考vux
参考vux移动端的ui组件,做了一个picker,测试在微信,uc主流浏览器能够正常工作。而在华为浏览器根本不能使用。而测试了vux的原有picker组件,发现在华为自带浏览器中,效果依然能够实现。
这时明白,原来vux也并非想的那么简单,兼容性这块做的很不错。或者是因为采用了vue的缘故?
实现代码如下:
<!DOCTYPE html>
<html lang="en"> <head>
<meta charset="UTF-8">
<title>制作移动端的picker参考vux</title>
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<style type="text/css">
* {
margin: ;
padding: ;
} .content {
position: absolute;
bottom: ;
height: %;
background: #fff;
width: %;
overflow: hidden;
display: none;
z-index:
} .title {
display: flex;
justify-content: center;
background-color: #fbf9fe;
} .title div {
height: 44px;
display: flex;
justify-content: center;
padding-left: 10px;
padding-right: 10px;
} .tip {
flex: ;
align-items: center;
} .cancel,
.finish {
width: 40px;
align-items: center;
} .cancel {
color: #;
} .finish { color: #FF9900;
} .dataBox {
position: relative;
border-top: 1px solid #f1f2f3;
display: flex;
height: %;
background: #f1f2f3;
overflow: hidden;
height: 170px;
} .middle {
position: absolute;
width: %;
height: 34px;
left: ;
top: 68px;
z-index: ;
background-image: linear-gradient(to bottom, #d0d0d0, #d0d0d0, transparent, transparent), linear-gradient(to top, #d0d0d0, #d0d0d0, transparent, transparent);
background-position: top, bottom;
background-size: % 1px;
background-repeat: no-repeat;
} .mengban {
position: absolute;
left: ;
top: ;
height: %;
margin: auto;
width: %;
z-index: ;
transform: translateZ(0px);
background-image: -webkit-linear-gradient(top, rgba(, , , 0.95), rgba(, , , 0.6)), -webkit-linear-gradient(bottom, rgba(, , , 0.95), rgba(, , , 0.6));
background-image: linear-gradient(to bottom, rgba(, , , 0.95), rgba(, , , 0.6)), linear-gradient(to top, rgba(, , , 0.95), rgba(, , , 0.6));
background-position: top, bottom;
background-size: % 68px;
background-repeat: no-repeat;
} .data {
position: absolute;
left: ;
top: ;
width: %;
z-index: ;
webkit-transform: translateZ();
-moz-transform: translateZ();
-ms-transform: translateZ();
-o-transform: translateZ();
transform: translateZ();
} .data div {
text-align: center;
font-size: 16px;
height: 34px;
line-height: 34px;
color: #;
} .active {
color: red !important;
} @-webkit-keyframes fadeInUp {
from {
opacity: ;
-webkit-transform: translate3d(, %, );
transform: translate3d(, %, );
} to {
opacity: ;
-webkit-transform: translate3d(, , );
transform: translate3d(, , );
}
} @keyframes fadeInUp {
from {
opacity: ;
-webkit-transform: translate3d(, %, );
transform: translate3d(, %, );
} to {
opacity: ;
-webkit-transform: translate3d(, , );
transform: translate3d(, , );
}
} .fadeInUp {
-webkit-animation-name: fadeInUp;
animation-name: fadeInUp;
} .animated {
-webkit-animation-duration: 1s;
animation-duration: 1s;
-webkit-animation-fill-mode: both;
animation-fill-mode: both;
} @-webkit-keyframes fadeIn {
from {
opacity: ;
} to {
opacity: ;
}
} @keyframes fadeIn {
from {
opacity: ;
} to {
opacity: ;
}
} .fadeIn {
-webkit-animation-name: fadeIn;
animation-name: fadeIn;
} @-webkit-keyframes fadeOut {
from {
opacity: ;
} to {
opacity: ;
display: none;
}
} @keyframes fadeOut {
from {
opacity: ;
} to {
opacity: ;
}
} .fadeOut {
-webkit-animation-name: fadeOut;
animation-name: fadeOut;
} @-webkit-keyframes fadeInDown {
from {
opacity: ;
-webkit-transform: translate3d(, -%, );
transform: translate3d(, -%, );
} to {
opacity: ;
-webkit-transform: translate3d(, , );
transform: translate3d(, , );
}
} @keyframes fadeInDown {
from {
opacity: ;
-webkit-transform: translate3d(, -%, );
transform: translate3d(, -%, );
} to {
opacity: ;
-webkit-transform: translate3d(, , );
transform: translate3d(, , );
}
} .fadeInDown {
-webkit-animation-name: fadeInDown;
animation-name: fadeInDown;
} .mask {
display: none;
position: fixed;
top: ;
bottom: ;
left: ;
right: ;
z-index: ;
background-color: rgba(, , , 0.5);
} @-webkit-keyframes fadeOutDown {
from {
opacity: ;
} to {
opacity: ;
-webkit-transform: translate3d(, %, );
transform: translate3d(, %, );
}
} @keyframes fadeOutDown {
from {
opacity: ;
} to {
opacity: ;
-webkit-transform: translate3d(, %, );
transform: translate3d(, %, );
}
} .fadeOutDown {
-webkit-animation-name: fadeOutDown;
animation-name: fadeOutDown;
}
</style>
</head> <body>
<button id="test">弹出</button>
<div class="content animated">
<div class="title">
<div class="cancel">取消</div>
<div class="tip">请选择</div>
<div class="finish" id="finish">完成</div>
</div>
<div class="dataBox" id="dataBox">
<div class="middle"></div>
<div class="mengban"></div>
<div class="data" id="data">
<div class="active">这是数据1</div>
<div>这是数据2</div>
<div>这是数据3</div>
<div>这是数据4</div>
<div>这是数据2</div>
<div>这是数据3</div>
<div>这是数据4</div>
<div>这是数据3</div>
<div>这是数据4</div>
<div>这是数据2</div>
<div>这是数据3</div>
<div>这是数据4</div>
</div>
</div>
</div>
<div class="mask animated"></div>
<script type="text/javascript">
//写成标准的组件形式
(function(window, document) {
//兼容性处理
function whichAnimationEvent() {
var t,
el = document.createElement("fakeelement"); var animations = {
"animation": "animationend",
"OAnimation": "oAnimationEnd",
"msAnimation":"msAnimationEnd",
"WebkitAnimation": "webkitAnimationEnd"
} for (t in animations) {
if (el.style[t] !== undefined) {
return animations[t];
}
}
}
//兼容性的过度结束事件
var animationEndEvent = whichAnimationEvent(); //transform兼容
function whichTransform() {
var el = document.createElement("fakeelement");
var transforms = ["webkitTransform", "msTransform", "OTransform", "transform"]; for (var t in transforms) {
if (el.style[transforms[t]] !== undefined) {
return transforms[t];
}
}
} //transition兼容性处理
function whichTransition() {
var el = document.createElement("fakeelement");
var transitions = ["transition", "OTransition", "WebkitTransition", "msTransition"]; for (var t in transitions) {
if (el.style[transitions[t]] !== undefined) {
return transitions[t];
}
}
}
//测试触发
var test = document.querySelector("#test");
var content = document.querySelector(".content"),
mask = document.querySelector(".mask"),
INITL = ; test.addEventListener("click", function() { content.style.display = "block";
mask.style.display = "block";
content.classList.remove("fadeOutDown");
content.classList.add("fadeInUp");
mask.classList.remove("fadeOut");
mask.classList.add("fadeIn"); }) //避免默认事件
document.addEventListener('touchmove', function(e) {
e.preventDefault();
}, { passive: false }); var box = document.getElementById('dataBox'),
data = document.getElementById("data"),
startY = ,
endY = ,
transformX = ,
h = parseInt(window.getComputedStyle(document.getElementById("data").children[], false).height),
n = document.getElementById("data").children.length; //初始化高度
function init(y) {
data.style = `transform: translate3d(0px, ${y}px, 0px)`;
}
init(INITL); //开始滑动
box.addEventListener("touchstart", function(e) {
console.log(data.style.transform);
startY = e.touches[].pageY;
transformX = data.style.transform.match(/translate3d\((-?\d+)px,\s*(-?\d+)px,\s*(\d+)px\)/i)[] ? data.style.transform.match(/translate3d\((-?\d+)px,\s*(-?\d+)px,\s*(\d+)px\)/i)[] : ; });
//滑动
box.addEventListener("touchmove", function(e) { var offsetY = e.touches[].pageY - startY;
data.style[whichTransform()] = `translate3d(,${parseInt(offsetY)+parseInt(transformX)}px,)`;
data.style[whichTransition()] = '100ms ease-out'; })
//结束滑动
box.addEventListener("touchend", function(e) {
transformX = data.style.transform.match(/translate3d\((-?\d+)px,\s*(-?\d+)px,\s*(\d+)px\)/i)[] ? data.style.transform.match(/translate3d\((-?\d+)px,\s*(-?\d+)px,\s*(-?\d+)px\)/i)[] : ; if (transformX > INITL) {
transformX = INITL;
} if (transformX < -(n - Math.round(INITL / h) - ) * h) {
transformX = -(n - Math.round(INITL / h) - ) * h;
}
var dis = Math.round(transformX / h) * h; data.style[whichTransform()] = `translate3d(,${dis}px,)`;
data.style[whichTransition()] = '300ms ease-out';
[].slice.apply(data.children).forEach(function(val, index) {
val.classList.remove("active");
}) data.children[Math.round(Math.abs(transformX - INITL) / h)].classList.add("active"); }) var finish = document.getElementById("finish");
var cancel = document.querySelector(".cancel"); //点击完成
finish.addEventListener("click", function() {
alert(data.querySelector(".active").innerHTML);
}) //点击取消
cancel.addEventListener("click", function() { content.classList.remove("fadeInUp");
content.classList.add("fadeOutDown");
mask.classList.remove("fadeIn");
mask.classList.add("fadeOut"); }) //从block到none的过渡处理
content.addEventListener(animationEndEvent, function() {
if (content.classList.contains('fadeOutDown')) {
content.style.display = "none";
}
});
mask.addEventListener(animationEndEvent, function() {
if (mask.classList.contains('fadeOut')) {
mask.style.display = "none";
}
});
})(window, document);
</script>
</body> </html>
滑动这块采用的是touch事件;
过渡效果利用的是css3的animation.css文件;
利用了一个以前没有应用的api:animationend,用来监控animation是否结束,结束后发生回调。
其它利用classlist对类进行增删。
做了一下兼容下,transform和transition的兼容性。
后面需要优化一下。
优化浏览器兼容性滑动。
<!DOCTYPE html>
<html lang="en"> <head>
<meta charset="UTF-8">
<title>制作移动端的picker参考vux</title>
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<style type="text/css">
* {
margin: ;
padding: ;
} .content {
position: absolute;
bottom: ;
height: %;
background: #fff;
width: %;
overflow: hidden;
display: none;
z-index:
} .title {
display: flex;
justify-content: center;
background-color: #fbf9fe;
} .title div {
height: 44px;
display: flex;
justify-content: center;
padding-left: 10px;
padding-right: 10px;
} .tip {
flex: ;
align-items: center;
} .cancel,
.finish {
width: 40px;
align-items: center;
} .cancel {
color: #;
} .finish { color: #FF9900;
} .dataBox {
position: relative;
border-top: 1px solid #f1f2f3;
display: flex;
height: %;
background: #f1f2f3;
overflow: hidden;
height: 170px;
} .middle {
position: absolute;
width: %;
height: 34px;
left: ;
top: 68px;
z-index: ;
background-image: linear-gradient(to bottom, #d0d0d0, #d0d0d0, transparent, transparent), linear-gradient(to top, #d0d0d0, #d0d0d0, transparent, transparent);
background-position: top, bottom;
background-size: % 1px;
background-repeat: no-repeat;
} .mengban {
position: absolute;
left: ;
top: ;
height: %;
margin: auto;
width: %;
z-index: ;
transform: translateZ(0px);
background-image: -webkit-linear-gradient(top, rgba(, , , 0.95), rgba(, , , 0.6)), -webkit-linear-gradient(bottom, rgba(, , , 0.95), rgba(, , , 0.6));
background-image: linear-gradient(to bottom, rgba(, , , 0.95), rgba(, , , 0.6)), linear-gradient(to top, rgba(, , , 0.95), rgba(, , , 0.6));
background-position: top, bottom;
background-size: % 68px;
background-repeat: no-repeat;
} .data {
position: absolute;
left: ;
top: ;
width: %;
z-index: ;
webkit-transform: translateZ();
-moz-transform: translateZ();
-ms-transform: translateZ();
-o-transform: translateZ();
transform: translateZ();
} .data div {
text-align: center;
font-size: 16px;
height: 34px;
line-height: 34px;
color: #;
} .active {
color: red !important;
} @-webkit-keyframes fadeInUp {
from {
opacity: ;
-webkit-transform: translate3d(, %, );
transform: translate3d(, %, );
} to {
opacity: ;
-webkit-transform: translate3d(, , );
transform: translate3d(, , );
}
} @keyframes fadeInUp {
from {
opacity: ;
-webkit-transform: translate3d(, %, );
transform: translate3d(, %, );
} to {
opacity: ;
-webkit-transform: translate3d(, , );
transform: translate3d(, , );
}
} .fadeInUp {
-webkit-animation-name: fadeInUp;
animation-name: fadeInUp;
} .animated {
-webkit-animation-duration: 1s;
animation-duration: 1s;
-webkit-animation-fill-mode: both;
animation-fill-mode: both;
} @-webkit-keyframes fadeIn {
from {
opacity: ;
} to {
opacity: ;
}
} @keyframes fadeIn {
from {
opacity: ;
} to {
opacity: ;
}
} .fadeIn {
-webkit-animation-name: fadeIn;
animation-name: fadeIn;
} @-webkit-keyframes fadeOut {
from {
opacity: ;
} to {
opacity: ;
display: none;
}
} @keyframes fadeOut {
from {
opacity: ;
} to {
opacity: ;
}
} .fadeOut {
-webkit-animation-name: fadeOut;
animation-name: fadeOut;
} @-webkit-keyframes fadeInDown {
from {
opacity: ;
-webkit-transform: translate3d(, -%, );
transform: translate3d(, -%, );
} to {
opacity: ;
-webkit-transform: translate3d(, , );
transform: translate3d(, , );
}
} @keyframes fadeInDown {
from {
opacity: ;
-webkit-transform: translate3d(, -%, );
transform: translate3d(, -%, );
} to {
opacity: ;
-webkit-transform: translate3d(, , );
transform: translate3d(, , );
}
} .fadeInDown {
-webkit-animation-name: fadeInDown;
animation-name: fadeInDown;
} .mask {
display: none;
position: fixed;
top: ;
bottom: ;
left: ;
right: ;
z-index: ;
background-color: rgba(, , , 0.5);
} @-webkit-keyframes fadeOutDown {
from {
opacity: ;
} to {
opacity: ;
-webkit-transform: translate3d(, %, );
transform: translate3d(, %, );
}
} @keyframes fadeOutDown {
from {
opacity: ;
} to {
opacity: ;
-webkit-transform: translate3d(, %, );
transform: translate3d(, %, );
}
} .fadeOutDown {
-webkit-animation-name: fadeOutDown;
animation-name: fadeOutDown;
}
</style>
</head> <body>
<button id="test">弹出</button>
<div class="content animated">
<div class="title">
<div class="cancel">取消</div>
<div class="tip">请选择</div>
<div class="finish" id="finish">完成</div>
</div>
<div class="dataBox" id="dataBox">
<div class="middle"></div>
<div class="mengban"></div>
<div class="data" id="data">
<div class="active">这是数据1</div>
<div>这是数据2</div>
<div>这是数据3</div>
<div>这是数据4</div>
<div>这是数据2</div>
<div>这是数据3</div>
<div>这是数据4</div>
<div>这是数据3</div>
<div>这是数据4</div>
<div>这是数据2</div>
<div>这是数据3</div>
<div>这是数据4</div>
</div>
</div>
</div>
<div class="mask animated"></div>
<script type="text/javascript">
//写成标准的组件形式
(function(window, document) {
//兼容性处理 var elementStyle = document.createElement('div').style; var vendor = function() {
var transformNames = {
webkit: 'webkitTransform',
Moz: 'MozTransform',
O: 'OTransform',
ms: 'msTransform',
standard: 'transform'
}; for (var key in transformNames) {
if (elementStyle[transformNames[key]] !== undefined) {
return key;
}
} return false;
}(); function prefixStyle(style) {
if (vendor === false) {
return false;
} if (vendor === 'standard') {
if (style === 'transitionEnd') {
return 'transitionend';
} if(style==="animationEnd"){
return 'animationEnd';
}
return style;
} return vendor + style.charAt().toUpperCase() + style.substr();
}
//测试触发
var test = document.querySelector("#test");
var content = document.querySelector(".content"),
mask = document.querySelector(".mask"),
INITL = ; test.addEventListener("click", function() { content.style.display = "block";
mask.style.display = "block";
content.classList.remove("fadeOutDown");
content.classList.add("fadeInUp");
mask.classList.remove("fadeOut");
mask.classList.add("fadeIn"); }) //避免默认事件
document.addEventListener('touchmove', function(e) {
e.preventDefault();
}, { passive: false }); var box = document.getElementById('dataBox'),
data = document.getElementById("data"),
startY = ,
endY = ,
transformX = ,
h = parseInt(window.getComputedStyle(document.getElementById("data").children[], false).height),
n = document.getElementById("data").children.length; //初始化高度
function init(y) {
data.style = `transform: translate3d(0px, ${y}px, 0px)`;
}
init(INITL); //开始滑动
box.addEventListener("touchstart", function(e) {
console.log(data.style.transform);
startY = e.touches[].pageY;
transformX = data.style.transform.match(/translate3d\((-?\d+)px,\s*(-?\d+)px,\s*(\d+)px\)/i)[] ? data.style.transform.match(/translate3d\((-?\d+)px,\s*(-?\d+)px,\s*(\d+)px\)/i)[] : ; });
//滑动
box.addEventListener("touchmove", function(e) { var offsetY = e.touches[].pageY - startY;
data.style[prefixStyle("transform")] = `translate3d(,${parseInt(offsetY)+parseInt(transformX)}px,)`;
data.style[prefixStyle("transition")] = '100ms ease-out'; })
//结束滑动
box.addEventListener("touchend", function(e) {
transformX = data.style.transform.match(/translate3d\((-?\d+)px,\s*(-?\d+)px,\s*(\d+)px\)/i)[] ? data.style.transform.match(/translate3d\((-?\d+)px,\s*(-?\d+)px,\s*(-?\d+)px\)/i)[] : ; if (transformX > INITL) {
transformX = INITL;
} if (transformX < -(n - Math.round(INITL / h) - ) * h) {
transformX = -(n - Math.round(INITL / h) - ) * h;
}
var dis = Math.round(transformX / h) * h; data.style[prefixStyle("transform")] = `translate3d(,${dis}px,)`;
data.style[prefixStyle("transition")] = '300ms ease-out';
[].slice.apply(data.children).forEach(function(val, index) {
val.classList.remove("active");
}) data.children[Math.round(Math.abs(transformX - INITL) / h)].classList.add("active"); }) var finish = document.getElementById("finish");
var cancel = document.querySelector(".cancel"); //点击完成
finish.addEventListener("click", function() {
alert(data.querySelector(".active").innerHTML);
}) //点击取消
cancel.addEventListener("click", function() { content.classList.remove("fadeInUp");
content.classList.add("fadeOutDown");
mask.classList.remove("fadeIn");
mask.classList.add("fadeOut"); }) //从block到none的过渡处理
content.addEventListener(prefixStyle("animationEnd"), function() {
if (content.classList.contains('fadeOutDown')) {
content.style.display = "none";
}
});
console.log(prefixStyle("transitionend"));
mask.addEventListener(prefixStyle("animationEnd"), function() {
if (mask.classList.contains('fadeOut')) {
mask.style.display = "none";
}
});
})(window, document);
</script>
</body> </html>
本文结束。
移动端的picker参考vux的更多相关文章
- 使用canvas制作的移动端color picker
使用canvas制作的移动端color picker 项目演示地址(用手机或者手机模式打开) 我在另一个中demo,需要用到color picker,但是找不到我需要的移动端color picker, ...
- 你还在为移动端选择器picker插件而捉急吗?
http://www.cnblogs.com/jingh/p/6381079.html 开题:得益于项目的上线,现在终于有时间来写一点点的东西,虽然很浅显,但是我感觉每经历一次项目,我就学到了很多的东 ...
- QML 移动端适配一个参考思路
参考: Qt Quick 准确的移动平台屏幕适配 qt qml 高宽自动适配android设备 QML 从无到有 (移动适配) 思路:以一个平台分辨率为基准(如320*480),考虑其与其它平台的比例 ...
- 服务端负载监控-参考srs服务器源码
#include <map> #include <stdio.h> using namespace std; struct SrsMemoryObject { void* pt ...
- vue移动端组件库vux使用小记
1.首先安装vux:npm install vux 2.安装vux-loader:npm install vux-loader 3.确认是否已安装less-loader:npm install ...
- H5移动端开发vue+vux
项目src中用到的npm包有(从编译打包到最终部署仍不能移除)1:vue 渐进式 JavaScript 框架 http://cn.vuejs.org/v2/guide/2: ...
- 基于vue + axios + lrz.js 微信端图片压缩上传
业务场景 微信端项目是基于Vux + Axios构建的,关于图片上传的业务场景有以下几点需求: 1.单张图片上传(如个人头像,实名认证等业务) 2.多张图片上传(如某类工单记录) 3.上传图片时期望能 ...
- vue中引入mintui、vux重构简单的APP项目
最近在学习vue时也了解到一些常用的UI组件,有用于PC的和用于移动端的.用于PC的有:Element(饿了么).iView等:用于移动端APP的有Vux.Mint UI(饿了么).Vant(有赞团队 ...
- uniapp中使用picker中的注意事项
APP端中picker点击后不弹出: 1.请确保picker标签里面嵌套了一个view,并且view里面有值 2.请确保picker中的默认值的格式跟该picker类型的值对应 例如下面: <v ...
随机推荐
- 从oracle往greenplum迁移,查询性能不满足要求的定位以及调优过程
一.前言 在一次对比oracle和greenplum查询性能过程中,由于greenplum查询性能不理想,因此进行定位分析,提升greenplum的查询性能 二.环境信息 初始情况下,搭建一个小的集群 ...
- STM32(10)——窗口看门狗
简介: 窗口看门狗(WWDG)通常被用来监测由外部干扰或不可预见的逻辑条件造成的应用程序背离正常的运行序列而产生的软件故障.除非递减计数器的值在 T6 位 (WWDG->CR 的第六位)变成 0 ...
- 『Python基础-7』for循环 & while循环
『Python基础-7』for循环 & while循环 目录: 循环语句 for循环 while循环 循环的控制语句: break,continue,pass for...else 和 whi ...
- tkinter的入门,估计也只能站门口
from tkinter import * import tkinter.messagebox as messagebox #创建一个继承frame的类,是所有小部件(widget的容器) #widg ...
- NoSQL入门第四天——事务与主从复制
一.Redis的事务 1.是什么 可以一次执行多个命令,本质是一组命令的集合.一个事务中的 所有命令都会序列化,按顺序地串行化执行而不会被其它命令插入,不许加塞 (更多请参见官网事务介绍) 2.能干什 ...
- 北京Uber优步司机奖励政策(3月31日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- vijos p1027休息中的小呆
休息中的小呆 描述 当大家在考场中接受考验(折磨?)的时候,小呆正在悠闲(欠扁)地玩一个叫“最初梦想”的游戏.游戏描述的是一个叫pass的有志少年在不同的时空穿越对抗传说中的大魔王chineseson ...
- P3379 【模板】最近公共祖先(LCA)
P3379 [模板]最近公共祖先(LCA) 题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询 ...
- DSP5509的RTC实验-第3篇
1. RTC实时时钟,不在过多介绍,本例程直接调用芯片支持库CSL的库函数,用起来比较简单 main() { CSL_init(); printf ("\nTESTING...\n" ...
- 180709-Java实现获取本机Ip的工具类
180709-Java实现获取本机Ip的工具类 获取本机Ip算是比较常见的一个需求场景了,比如业务报警,可能就会带上出问题的机器IP,方便直接上去看日志定位问题,那么问题来了,如何获取机器IP呢? I ...