UNPKG

vue-weui-expand

Version:

WeUI 的轻量级 js 封装

558 lines (471 loc) 20.7 kB
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}