移动端的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 ...
随机推荐
- 发现新大陆QuickBurro中间件 http://www.quickburro.org
可以做手机.网页,三层C/S?这么神?
- Python学习笔记三:数据类型
数据类型 整数int 32位机器,-2**31~2**31-1,即-2147483648~2147483647(4亿多) 64位机器,-2**63~2**63-1,非常大了. 长整型long 没有位数 ...
- 反射vs简单工厂模式
interface Computer { void printpc(); } class lenovo implements Computer { @Override public void prin ...
- java 第八章 异常处理
一.异常简介 (一)定义: 运行期间出现的错误,而不是编译时的语法错误 例如: 1.打开一个不存在的文件 2.网络连接中断 3.数学类错误 4.操作数组越界等 (二)异常的继承树 (三)异常类的体系结 ...
- 机器学习的5种“兵法"
大数据文摘作品,欢迎个人转发朋友圈,自媒体.媒体.机构转载务必申请授权,后台留言“机构名称+转载”,申请过授权的不必再次申请,只要按约定转载即可. 作者:Jason Brownlee 译者:Clair ...
- Visual Studio 起始页中不显示最近使用的项目的解决办法
将 HKEY_CURRENT_USER/Software/Microsoft/Windows/CurrentVersion/Policies/Explorer/NoRecentDocsHistory的 ...
- 关于Python的多重排序
Python预置的list.sort().sorted()方法可实现各种数组的排序,但支持的只限于一个key,如果要多重排序,目前所知的方法只有自定义了. Help on built-in funct ...
- 【白书训练指南】(UVa10755)Garbage Heap
先po代码,之后把我那几个不太明了的知识点讲讲,巩固以下.三维的扫描线算法想要掌握还真是有一定的难度的. 代码 #include <iostream> #include <cstri ...
- MySQL日期、字符串、时间戳互转
平时比较常用的时间.字符串.时间戳之间的互相转换,虽然常用但是几乎每次使用时候都喜欢去搜索一下用法:本文将作为一个笔记,整理一下三者之间的 转换(即:date转字符串.date转时间戳.字符串转dat ...
- 用IDEA编写spark的WordCount
我习惯用Maven项目 所以用IDEA新建一个Maven项目 下面是pom文件 我粘上来吧 <?xml version="1.0" encoding="UTF-8& ...