UNPKG

vue-weui-expand

Version:

WeUI 的轻量级 js 封装

266 lines (223 loc) 9.44 kB
//picker已经写vue版本的,觉得很不方便调用,故重写了js版本的 import {_Substitute} from '../comm/comm.js' function show ({data,setValue=[],level,yes,no,shadeClose=true}={}){ let items=[]; let options=[]; for(let i=0; i<level;i++){ options=[...options,{ init_location: 102, pull_location_y: 0, styleObject: 'transform:translate3d(0px, 102px, 0px);transition:all 0s ease 0s' }]; } //初始化数据 let recursive=function(d,l,f,de){ let items=[]; let child=undefined; let tp=102; let find=false; d.forEach((el,index)=>{ items=[...items,{text:el.text,value:el.value}]; if(f>de.length-1){ if(index==0){ child=el.child; } } else if(de[f]!=undefined && de[f]==el.value&&f<level){ //给默认项设置当前位置 options[f].init_location=tp; options[f].styleObject='transform:translate3d(0px, '+tp+'px, 0px);transition:all 0s ease 0s'; find=true; child=el.child; }else if(de[f]!=undefined&&find==false){ tp-=34;//未找到位置当前位置向前排 } }); l=[...l,items]; if(child!=undefined&&f<level){ //继续查找子项数据 l= recursive(child,l,(f+1),de); } return l; } let areaData=recursive.call(this,data,[],0,setValue); items=areaData;//滚动数据实初始化,如果没有默认,显示第一个项数据 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<level;i++){ let itemsHtml=''; if(items[i]!=undefined){ items[i].forEach(el=>{ itemsHtml+=_Substitute(tpl_itemHtml,{text:el.text}); }); } let html=_Substitute(tpl_itemBaseHtml,{styleObject:options[i].styleObject,items:itemsHtml,index:i}); r_itemHtml+=html; } 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 newNode = window.document.createElement("div"); newNode.id=Number(Math.random().toString().substr(3,length) + Date.now()).toString(36); newNode.innerHTML = innerHtml; 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; options[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-options[index].pull_location_y+options[index].init_location; //下/上拉动的时候,超出列表范围,最多空白34px if(tp>136){ tp=136; } let len= data[index].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); } } options[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=options[index].styleObject; },false); group[i].addEventListener('touchend',()=>{ let index=event.currentTarget.dataset.index; let tp=event.changedTouches[0].clientY-options[index].pull_location_y+options[index].init_location; //下/上拉超同列表范围不得超过34px if(tp>102){ tp=102; } let len= items[index].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;//记录原来的位置 options[index].init_location=tp;//记录最后的位置,也是下一次的起始位置 //设置选项 options[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=options[index].styleObject; //拖动时如果当前选项不变,即数据不需要变化 if(oldpostion!=tp){ //重置子项数据 let child=undefined; options.forEach((el,f)=>{ if(f>index){ el.init_location=102; el.styleObject='transform:translate3d(0px, 102px, 0px);transition:all 0.3s ease 0s'; } let dataIndex=Math.abs((el.init_location-102))/34; if(f>0){ if(child!=undefined){ if(child[dataIndex]!=undefined){ child=child[dataIndex].child; }else{ child=[]; } } }else{ child=data[dataIndex].child; } if(child!=undefined){ items[f+1]=child.map(item=>{ return {text:item.text,value:item.value}; }); }else{ items[f+1]=[]; } }); } //chnage 到元素 for(let i=parseInt(index) +1;i<level;i++){ let itemsHtml=''; if(items[i].forEach){ items[i].forEach(el=>{ itemsHtml+=_Substitute(tpl_itemHtml,{text:el.text}); }); } let currerNode=newNode.getElementsByClassName('weui-picker__content')[i]; currerNode.innerHTML=itemsHtml; currerNode.style=options[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 r=[]; options.forEach((el,index)=>{ if(index<level){ let elindex= Math.abs((options[index].init_location-102))/34; if(items[index]!=undefined&&items[index].length>0){ let item= items[index][elindex]; r=[...r,item]; } } }); remove(); if(yes!=undefined)yes(r); },false); } function install(Vue){ Vue.prototype.picker={show}; } export {show,install}