jQuery移動端的城市三級聯(lián)動選擇器

閑話少敘,先上圖:


如果是這樣的,代碼:


JS 里要寫的
數(shù)據(jù)結(jié)構(gòu)大概都是這樣的吧 ^:^

什么,還要代碼?

HTML:

<div>

? ? <label? class="am-padding-xs">選擇區(qū)域</label>

? ? <input class="am-text-left am-text-xs"id="area"type="text"value="陜西,西安,碑林">

? ? <input type="hidden"? name="areaId"? id="areaId"? value="27,428,2920"? required>

</div>

JS:

// 城市級聯(lián)選擇

varcityData;

$.ajax({

url:'/res/common/city.json',

async:false,

success:function(data){

cityData=data;

}

});

vararea =newLArea();

area.init({

'trigger':'#area',// 觸發(fā)選擇控件的文本框,同時選擇完畢后name屬性輸出到該位置

'valueTo':'#areaId',// 選擇完畢后id屬性輸出到該位置

'keys': {

city_id:'city_id',

title:'title'

},

'type':1,// 數(shù)據(jù)源類型

'data': cityData// 數(shù)據(jù)源

});

area.value=[27,428,2920];// 初始位置,注意:該方法并不會影響到input的value

JS插件代碼:

window.LArea=(function() {

varMobileArea=function() {

this.gearArea;

this.data;

this.index=0;

this.value=[0,0,0];

}

MobileArea.prototype={

init:function(params) {

this.params=params;

this.trigger=document.querySelector(params.trigger);

if(params.valueTo){

this.valueTo=document.querySelector(params.valueTo);

}

this.keys=params.keys;

this.type=params.type||1;

switch(this.type) {

case1:

case2:

break;

default:

thrownewError('錯誤提示: 沒有這種數(shù)據(jù)源類型');

break;

}

this.bindEvent();

},

getData:function(callback) {

var_self=this;

if(typeof_self.params.data=="object") {

_self.data=_self.params.data;

callback();

}else{

varxhr=newXMLHttpRequest();

xhr.open('get', _self.params.data);

xhr.onload=function(e) {

if((xhr.status>=200&&xhr.status<300)||xhr.status===0) {

varresponseData=JSON.parse(xhr.responseText);

_self.data=responseData.data;

if(callback) {

callback()

};

}

}

xhr.send();

}

},

bindEvent:function() {

var_self=this;

//呼出插件

functionpopupArea(e) {

_self.gearArea=document.createElement("div");

_self.gearArea.className="gearArea";

_self.gearArea.innerHTML='

'+

'

'+

'

取消
'+

'

確定
'+

''+

'

'+

'

'+

'

'+

'

'+

'

'+

''+

''+

'

'+

'

'+

'

'+

''+

''+

'

'+

'

'+

'

'+

''+

''+

''+

''+

'';

document.body.appendChild(_self.gearArea);

areaCtrlInit();

varlarea_cancel=_self.gearArea.querySelector(".larea_cancel");

larea_cancel.addEventListener('touchstart',function(e) {

_self.close(e);

});

varlarea_finish=_self.gearArea.querySelector(".larea_finish");

larea_finish.addEventListener('touchstart',function(e) {

_self.finish(e);

});

vararea_province=_self.gearArea.querySelector(".area_province");

vararea_city=_self.gearArea.querySelector(".area_city");

vararea_county=_self.gearArea.querySelector(".area_county");

area_province.addEventListener('touchstart', gearTouchStart);

area_city.addEventListener('touchstart', gearTouchStart);

area_county.addEventListener('touchstart', gearTouchStart);

area_province.addEventListener('touchmove', gearTouchMove);

area_city.addEventListener('touchmove', gearTouchMove);

area_county.addEventListener('touchmove', gearTouchMove);

area_province.addEventListener('touchend', gearTouchEnd);

area_city.addEventListener('touchend', gearTouchEnd);

area_county.addEventListener('touchend', gearTouchEnd);

}

//初始化插件默認(rèn)值

functionareaCtrlInit() {

_self.gearArea.querySelector(".area_province").setAttribute("val", _self.value[0]);

_self.gearArea.querySelector(".area_city").setAttribute("val", _self.value[1]);

_self.gearArea.querySelector(".area_county").setAttribute("val", _self.value[2]);

switch(_self.type) {

case1:

_self.setGearTooth(_self.data);

break;

case2:

_self.setGearTooth(_self.data[0]);

break;

}

}

//觸摸開始

functiongearTouchStart(e) {

e.preventDefault();

vartarget=e.target;

while(true) {

if(!target.classList.contains("gear")) {

target=target.parentElement;

}else{

break

}

}

clearInterval(target["int_"+target.id]);

target["old_"+target.id]=e.targetTouches[0].screenY;

target["o_t_"+target.id]=(newDate()).getTime();

vartop=target.getAttribute('top');

if(top) {

target["o_d_"+target.id]=parseFloat(top.replace(/em/g,""));

}else{

target["o_d_"+target.id]=0;

}

target.style.webkitTransitionDuration=target.style.transitionDuration='0ms';

}

//手指移動

functiongearTouchMove(e) {

e.preventDefault();

vartarget=e.target;

while(true) {

if(!target.classList.contains("gear")) {

target=target.parentElement;

}else{

break

}

}

target["new_"+target.id]=e.targetTouches[0].screenY;

target["n_t_"+target.id]=(newDate()).getTime();

varf=(target["new_"+target.id]-target["old_"+target.id])*30/window.innerHeight;

target["pos_"+target.id]=target["o_d_"+target.id]+f;

target.style["-webkit-transform"]='translate3d(0,'+target["pos_"+target.id]+'em,0)';

target.setAttribute('top', target["pos_"+target.id]+'em');

if(e.targetTouches[0].screenY<1){

gearTouchEnd(e);

};

}

//離開屏幕

functiongearTouchEnd(e) {

e.preventDefault();

vartarget=e.target;

while(true) {

if(!target.classList.contains("gear")) {

target=target.parentElement;

}else{

break;

}

}

varflag=(target["new_"+target.id]-target["old_"+target.id])/(target["n_t_"+target.id]-target["o_t_"+target.id]);

if(Math.abs(flag)<=0.2) {

target["spd_"+target.id]=(flag<0?-0.08:0.08);

}else{

if(Math.abs(flag)<=0.5) {

target["spd_"+target.id]=(flag<0?-0.16:0.16);

}else{

target["spd_"+target.id]=flag/2;

}

}

if(!target["pos_"+target.id]) {

target["pos_"+target.id]=0;

}

rollGear(target);

}

//緩動效果

functionrollGear(target) {

vard=0;

varstopGear=false;

functionsetDuration() {

target.style.webkitTransitionDuration=target.style.transitionDuration='200ms';

stopGear=true;

}

clearInterval(target["int_"+target.id]);

target["int_"+target.id]=setInterval(function() {

varpos=target["pos_"+target.id];

varspeed=target["spd_"+target.id]*Math.exp(-0.03*d);

pos+=speed;

if(Math.abs(speed)>0.1) {}else{

varb=Math.round(pos/2)*2;

pos=b;

setDuration();

}

if(pos>0) {

pos=0;

setDuration();

}

varminTop=-(target.dataset.len-1)*2;

if(pos

pos=minTop;

setDuration();

}

if(stopGear) {

vargearVal=Math.abs(pos)/2;

setGear(target, gearVal);

clearInterval(target["int_"+target.id]);

}

target["pos_"+target.id]=pos;

target.style["-webkit-transform"]='translate3d(0,'+pos+'em,0)';

target.setAttribute('top', pos+'em');

d++;

},30);

}

//控制插件滾動后停留的值

functionsetGear(target, val) {

val=Math.round(val);

target.setAttribute("val", val);

switch(_self.type) {

case1:

_self.setGearTooth(_self.data);

break;

case2:

switch(target.dataset['areatype']){

case'area_province':

_self.setGearTooth(_self.data[0]);

break;

case'area_city':

varref=target.childNodes[val].getAttribute('ref');

varchildData=[];

varnextData=_self.data[2];

for(variinnextData) {

if(i==ref){

childData=nextData[i];

break;

}

};

_self.index=2;

_self.setGearTooth(childData);

break;

}

}

}

_self.getData(function() {

_self.trigger.addEventListener('click', popupArea);

});

},

//重置節(jié)點個數(shù)

setGearTooth:function(data) {

var_self=this;

varitem=data||[];

varl=item.length;

vargearChild=_self.gearArea.querySelectorAll(".gear");

vargearVal=gearChild[_self.index].getAttribute('val');

varmaxVal=l-1;

if(gearVal>maxVal) {

gearVal=maxVal;

}

gearChild[_self.index].setAttribute('data-len', l);

if(l>0) {

varid=item[gearVal][this.keys['city_id']];

varchildData;

switch(_self.type) {

case1:

childData=item[gearVal].children

break;

case2:

varnextData=_self.data[_self.index+1]

for(variinnextData) {

if(i==id){

childData=nextData[i];

break;

}

};

break;

}

varitemStr="";

for(vari=0; i

itemStr+="

"+item[i][this.keys['title']]+"
";

}

gearChild[_self.index].innerHTML=itemStr;

gearChild[_self.index].style["-webkit-transform"]='translate3d(0,'+(-gearVal*2)+'em,0)';

gearChild[_self.index].setAttribute('top',-gearVal*2+'em');

gearChild[_self.index].setAttribute('val', gearVal);

_self.index++;

if(_self.index>2) {

_self.index=0;

return;

}

_self.setGearTooth(childData);

}else{

gearChild[_self.index].innerHTML="

";

gearChild[_self.index].setAttribute('val',0);

if(_self.index==1){

gearChild[2].innerHTML="

";

gearChild[2].setAttribute('val',0);

}

_self.index=0;

}

},

finish:function(e) {

var_self=this;

vararea_province=_self.gearArea.querySelector(".area_province");

vararea_city=_self.gearArea.querySelector(".area_city");

vararea_county=_self.gearArea.querySelector(".area_county");

varprovinceVal=parseInt(area_province.getAttribute("val"));

varprovinceText=area_province.childNodes[provinceVal].textContent;

varprovinceCode=area_province.childNodes[provinceVal].getAttribute('ref');

varcityVal=parseInt(area_city.getAttribute("val"));

varcityText=area_city.childNodes[cityVal].textContent;

varcityCode=area_city.childNodes[cityVal].getAttribute('ref');

varcountyVal=parseInt(area_county.getAttribute("val"));

varcountyText=area_county.childNodes[countyVal].textContent;

varcountyCode=area_county.childNodes[countyVal].getAttribute('ref');

_self.trigger.value=provinceText+((cityText)?(','+cityText):(''))+((countyText)?(','+countyText):(''));

_self.value=[provinceVal, cityVal, countyVal];

if(this.valueTo){

this.valueTo.value=provinceCode+((cityCode)?(','+cityCode):(''))+((countyCode)?(','+countyCode):(''));

}

_self.close(e);

},

close:function(e) {

e.preventDefault();

var_self=this;

varevt=newCustomEvent('input');

_self.trigger.dispatchEvent(evt);

document.body.removeChild(_self.gearArea);

_self.gearArea=null;

}

}

returnMobileArea;

})()

what!你還不會,那就@me 524035394@qq.com

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • ¥開啟¥ 【iAPP實現(xiàn)進入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開一個線程,因...
    小菜c閱讀 7,295評論 0 17
  • 在一些電商類的微信小程序中,地址選擇這個功能一般是必備的,一般的收貨信息都需要有一個能選擇省市縣的控件,當(dāng)然也有些...
    第九程序官方閱讀 4,175評論 0 6
  • 作者: 惟湛 如何調(diào)整ABAP程序的性能(copy) 7、兩個內(nèi)表添加使用批量增加代替逐行不推薦Loop at i...
    SmalltalkVoice閱讀 7,805評論 7 18
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,506評論 19 139
  • 我一直在偽裝自己,試圖掩蓋內(nèi)心那個真實的我。 我想要走出一條路,然后有很多的人跟著我的腳步。 人生就像是電影中的蒙...
    懶妹z閱讀 140評論 0 0

友情鏈接更多精彩內(nèi)容