vue-weui-expand
Version:
WeUI 的轻量级 js 封装
558 lines (471 loc) • 20.7 kB
JavaScript
import {
leap,
lastDay,_Substitute
} from '../comm/comm.js';
function show({
type = 'datetime',
startDate = '',
endDate = '',
setValue,
shadeClose=true,
yes,
no
} = {}) {
let
options = [],
min = [],
max = [],
itemStyle = [],
selectItem = [],
suffix=['年','月','日','时','分','秒'];
//初始化数据
{
let syear, eyear;
let sDate, eDate;
var nowdate = new window.Date();
for (let i = 0; i < 6; i++) {
itemStyle = [...itemStyle, {
init_location: 102,
pull_location_y: 0,
styleObject:"transform:translate3d(0px, 102px, 0px);transition:all 0s ease 0s;"
}];
}
if (startDate == "") {
sDate = new Date((nowdate.getFullYear() - 10) + '/' + (nowdate.getMonth() + 1) + '/' + nowdate.getDate() + ' ' + nowdate.getHours() + ':' + nowdate.getMinutes() + ':' + nowdate.getSeconds());
syear = sDate.getFullYear();
} else {
sDate = new Date(startDate.replace(/-/g, "/"));
syear = sDate.getFullYear();
}
if (endDate == "") {
eDate = new Date((nowdate.getFullYear() + 10) + '/' + (nowdate.getMonth() + 1) + '/' + nowdate.getDate() + ' ' + nowdate.getHours() + ':' + nowdate.getMinutes() + ':' + nowdate.getSeconds());
eyear = eDate.getFullYear();
} else {
eDate = new Date(endDate.replace(/-/g, "/"));
eyear = eDate.getFullYear();
}
for (let index = syear; index <= eyear; index++) {
options[0] = [...options[0] == undefined ? [] : options[0], index];
}
for (let i = 0; i <= 59; i++) {
options[4] = [...options[4] == undefined ? [] : options[4], {
select: true,
value: i
}];
options[5] = [...options[5] == undefined ? [] : options[5], {
select: true,
value: i
}];
if (i < 13&&i>0) {
options[1] = [...(options[1] == undefined ? [] : options[1]), {
select: true,
value: i
}];
}
if (i < 32&&i>0) {
options[2] = [...options[2] == undefined ? [] : options[2], {
select: true,
value: i
}];
}
if (i < 24) {
options[3] = [...options[3] == undefined ? [] : options[3], {
select: true,
value: i
}];
}
}
min[0] = syear;
max[0] = eyear;
min[1] = sDate.getMonth() + 1;
min[2] = sDate.getDate();
min[3] = sDate.getHours();
min[4] = sDate.getMinutes();
min[5] = sDate.getSeconds();
max[1] = eDate.getMonth() + 1;
max[2] = eDate.getDate();
max[3] = eDate.getHours();
max[4] = eDate.getMinutes();
max[5] = eDate.getSeconds();
if (setValue != undefined && setValue != '') {
nowdate = new Date(setValue);
}
//如果当前时间在可选内,那么默认选中的当前时间,若不然默认是最小时间
if (nowdate >= sDate && nowdate <= eDate) {
selectItem[0] = nowdate.getFullYear();
selectItem[1] = nowdate.getMonth() + 1;
selectItem[2] = nowdate.getDate();
selectItem[3] = nowdate.getHours();
selectItem[4] = nowdate.getMinutes();
selectItem[5] = nowdate.getSeconds();
//确保最大最小时间的可选项
for (let i = 0; i < 5; i++) {
if (selectItem[i] == min[0]) {
options[i + 1].forEach(item => {
if (item.value < min[i + 1]) {
item.select = false;
}
});
} else {
break;
}
}
for (let i = 0; i < 5; i++) {
if (selectItem[i] == max[0]) {
options[i + 1].forEach(item => {
if (item.value > max[i + 1]) {
item.select = false;
}
});
} else {
break;
}
}
let top = 0;
for (let i = 0; i < 6; i++) {
top = 102;
options[i].forEach(item => {
if (i == 0) {
//年是number数组
if (item < selectItem[i]) {
top -= 34;
}
} else {
//月日...对象数组
if (item.select && item.value < selectItem[i]) {
top -= 34;
}
}
});
itemStyle[i].styleObject = "transform:translate3d(0px, " + top + "px, 0px);transition:all 0.3s ease 0s;";
itemStyle[i].init_location = top; //记录最后的位置,也是下一次的起始位置
}
} else {
let setSelect = [-1, -1, -1, -1, -1];
//弹出窗口时要加载正确的数据,设置最小可访问
for (let i = 1; i < 6; i++) {
options[i].forEach((item) => {
if (item.value < min[i]) {
item.select = false;
} else {
if (setSelect[i] == -1) {
setSelect[i] = item.value;
}
}
if (i == 2) {
if (leap(min[0]) && setSelect[0] == 2 && item.value > 29) {
item.select = false;
} else if (!(leap(min[0]) && setSelect[0] == 2) && item.value > 28) {
item.select = false;
}
}
});
}
//验证最大日期
for (let i = 0; i < 5; i++) {
if (max[i] == min[i]) {
options[i + 1].forEach(item => {
if (item.value > max[i + 1]) {
item.select = false;
}
});
} else {
break;
}
}
selectItem[0] = min[0];
selectItem[1] = setSelect[0];
selectItem[2] = setSelect[1];
selectItem[3] = setSelect[2];
selectItem[4] = setSelect[3];
selectItem[5] = setSelect[4];
}
}
//初始化完成
//加载doc无素及事件
{
var innerHtml=`
<div class="weui-mask weui-animate-fade-in" ></div>
<div class="weui-picker weui-animate-slide-up">
<div class="weui-picker__hd">
<a data-action="cancel" class="weui-picker__action" >取消</a>
<a data-action="select" class="weui-picker__action" >确定</a>
</div>
<div class="weui-picker__bd">
{r_itemHtml}
</div>
</div>
`;
let tpl_itemBaseHtml=`
<div class="weui-picker__group" data-index="{index}">
<div class="weui-picker__mask" ></div>
<div class="weui-picker__indicator"></div>
<div class="weui-picker__content" style="{styleObject}">{items}</div>
</div>
`;
let tpl_itemHtml='<div class="weui-picker__item" >{text}</div>';
let r_itemHtml='';
for(let i=0;i<(type=='date'?3:6);i++){
let r_singItems='';
if(i==0){
options[i].forEach(item=>{
r_singItems+=_Substitute(tpl_itemHtml,{text:item+suffix[i]});
});
}else{
options[i].forEach(item=>{
r_singItems+=_Substitute(tpl_itemHtml,{text:(item.value<10?('0'+item.value):item.value)+suffix[i]});
});
}
r_itemHtml+=_Substitute(tpl_itemBaseHtml,{index:i,styleObject:itemStyle[i].styleObject,items:r_singItems});
}
let html=_Substitute(innerHtml,{r_itemHtml:r_itemHtml});
let newNode = window.document.createElement("div");
newNode.id=Number(Math.random().toString().substr(3,length) + Date.now()).toString(36);
newNode.innerHTML = html;
window.document.getElementsByTagName('body')[0].appendChild(newNode);
//注册事件
//动态生成document后,给相关的document注册事件
let group= newNode.getElementsByClassName('weui-picker__group');
for(let i=0;i<group.length;i++){
group[i].addEventListener('touchstart',()=>{
let index=event.currentTarget.dataset.index;
itemStyle[index].pull_location_y = event.touches[0].clientY;
},false);
group[i].addEventListener('touchmove',()=>{
let index=event.currentTarget.dataset.index;
let tp =
event.touches[0].clientY -
itemStyle[index].pull_location_y +
itemStyle[index].init_location;
//下/上拉动的时候,超出列表范围,最多空白34px
if (tp > 136) {
tp = 136;
}
let len = 0;
if (index == 0) {
len = options[0].length;
} else {
len = options[index].filter(function(item) {
return item.select;
}).length;
}
if (len > 4) {
if (tp < -((len - 4 + 1) * 34)) {
tp = -((len - 4 + 1) * 34);
}
} else {
if (tp < 102 - len * 34) {
tp = 102 - len * 34;
}
}
itemStyle[index].styleObject='transform:translate3d(0px, '+tp+'px, 0px);transition:all 0s ease 0s';
newNode.getElementsByClassName('weui-picker__group')[index].getElementsByClassName('weui-picker__content')[0].style=itemStyle[index].styleObject;
},false);
group[i].addEventListener('touchend',()=>{
let index=event.currentTarget.dataset.index;
let tp =
event.changedTouches[0].clientY -
itemStyle[index].pull_location_y +
itemStyle[index].init_location;
//下/上拉超同列表范围不得超过34px
if (tp > 102) {
tp = 102;
}
let len = 0;
if (index == 0) {
len = options[0].length;
} else {
len = options[index].filter(function(item) {
return item.select;
}).length;
}
if (len > 4) {
if (tp < -((len - 4) * 34)) {
tp = -((len - 4) * 34);
}
} else {
if (tp < 102 - (len - 1) * 34) {
tp = 102 - (len - 1) * 34;
}
}
//处理必须选中一项
if (tp % 34 != 0) {
if (tp % 34 > 17) {
tp = parseInt(tp / 34 + 1) * 34;
} else {
tp = parseInt(tp / 34) * 34;
}
}
//动画
let oldpostion=options[index].init_location;//记录原来的位置
itemStyle[index].styleObject="transform:translate3d(0px, " + tp + "px, 0px);transition:all 0.3s ease 0s";
itemStyle[index].init_location = tp; //记录最后的位置,也是下一次的起始位置
//计算当前的选项是什么
let currer_index = 0;
if (itemStyle[index].init_location >= 0) {
currer_index = (102 - itemStyle[index].init_location) / 34;
} else {
currer_index = Math.abs(itemStyle[index].init_location) / 34 + 3;
}
if (index == 0) {
selectItem[0] = options[0][currer_index];
} else {
selectItem[index]= options[index].filter(item=>item.select)[currer_index].value;
}
let Reload=function(i){
if(i<5){
options[5].forEach(item=>{item.select=true;});
}
if(i<4){
options[4].forEach(item=>{item.select=true;});
}
if(i<3){
options[3].forEach(item=>{item.select=true;});
}
if(i<2){
options[2].forEach(item=>{
if(item.value<=lastDay(selectItem[0],selectItem[1]))
{
item.select=true;
}else{
item.select=false;
}}
);
}
if(i<1){
options[1].forEach(item=>{item.select=true;});
}
}
//当前列表滚动时,此列以后的列数据重置
Reload.call(this,index);
let SetDefault=function(t){
for(let i=t+1;i<6;i++){
let loactiontop=102;
if(i==2){
let allSelect= options[2].filter(item => item.select);
let thisMonthDay=allSelect[allSelect.length-1].value;
if(selectItem[2]>thisMonthDay){
selectItem[2]=thisMonthDay;
}
}
options[i].forEach(item=>{
//设置默认值
if(selectItem[i]>item.value&&item.select){
loactiontop-=34;
}
}
);
itemStyle[i].styleObject ="transform:translate3d(0px, "+loactiontop+"px, 0px);transition:all 0s ease 0s;";
selectItem[i]=options[i].filter(item => item.select)[Math.abs(loactiontop-102)/34].value;
itemStyle[i].init_location=loactiontop;
}
}
//当前年是最小限制的
for(let i=0;i<5;i++){
if(min[i]==selectItem[i]){
let loactiontop=102;
options[i+1].forEach(item=>{
if(item.value<min[i+1]){
item.select=false;
}else{
//设置默认值
if(selectItem[i+1]>item.value){
loactiontop-=34;
}
}
}
);
itemStyle[i+1].styleObject="transform:translate3d(0px, "+loactiontop+"px, 0px);transition:all 0s ease 0s;";
selectItem[i+1]=options[i+1].filter(item => item.select)[Math.abs(loactiontop-102)/34].value;
itemStyle[i+1].init_location=loactiontop;
}else{
if(i!=0){
SetDefault.call(this,i);
}
break;
}
}
//当前年是最大限制的
for(let i=0;i<5;i++){
if(selectItem[i]==max[i]){
let loactiontop=102;
//超过部分将隐藏起来
options[i+1].forEach(item=>{
if(item.value>max[i+1])
{
item.select=false;
}else{
loactiontop-=34;
}
}
);
//如果当前选中的部分大于最大可选部分即默认选择最大可选
if(selectItem[i+1]>max[i+1]){
itemStyle[i+1].styleObject ="transform:translate3d(0px, "+loactiontop+"px, 0px);transition:all 0s ease 0s;";
selectItem[i+1]=max[i+1];
itemStyle[i+1].init_location=loactiontop;
}
}else{
break;
}
}
//当前年是中间的
if(!(selectItem[0]==options[0][0]&&selectItem[0]!=options[0][options[0].length-1])){
SetDefault.call(this,0);
}
//处理反馈到doc
itemStyle[index].styleObject='transform:translate3d(0px, '+tp+'px, 0px);transition:all 0.3s ease 0s';
newNode.getElementsByClassName('weui-picker__group')[index].getElementsByClassName('weui-picker__content')[0].style=itemStyle[index].styleObject;
//拖动时如果当前选项不变,即数据不需要变化
if(oldpostion!=tp){
//chnage 到元素
for(let i=parseInt(index) +1;i<(type=='date'?3:6);i++){
let itemsHtml='';
options[i].forEach(el=>{
if(el.select)
itemsHtml+=_Substitute(tpl_itemHtml,{text:(el.value<10?'0'+el.value:el.value)+suffix[i]});
});
let currerNode=newNode.getElementsByClassName('weui-picker__content')[i];
currerNode.innerHTML=itemsHtml;
currerNode.style=itemStyle[i].styleObject;
}
}
},false);
}
//滑动事件处理完成
let remove=function(){
let up= newNode.getElementsByClassName('weui-animate-fade-in');
if(up.length>0){
up[0].setAttribute('class','weui-mask weui-animate-fade-out');
}
let down= newNode.getElementsByClassName('weui-animate-slide-up');
if(down.length>0){
down[0].setAttribute('class','weui-picker weui-animate-slide-down');
}
setTimeout(function(){ window.document.getElementsByTagName('body')[0].removeChild(newNode);},300);
}
//回调事件注册
newNode.getElementsByClassName('weui-picker__action')[0].addEventListener('click',()=>{
remove();
if(no!=undefined)no();
},false);
newNode.getElementsByClassName('weui-mask')[0].addEventListener('click',()=>{
if(shadeClose){
remove();
if(no!=undefined)no();
}
},false);
newNode.getElementsByClassName('weui-picker__action')[1].addEventListener('click',()=>{
let v= selectItem[0] +"-" + selectItem[1] + "-" +selectItem[2] ;
if(type==''||type=='datetime'){
v+=" " + selectItem[3] + ":" +selectItem[4] + ":" + selectItem[5];
}
remove();
if(yes!=undefined)yes(v);
},false);
}
}
function install(Vue){
Vue.prototype.datepicker={show};
}
export {show,install}