jQuery移动端的城市三级联动选择器

闲话少叙,先上图:


如果是这样的,代码:


JS 里要写的
数据结构大概都是这样的吧 ^:^

什么,还要代码?

HTML:

<div>

    <label  class="am-padding-xs">选择区域</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:

// 城市级联选择

varcityData;

$.ajax({

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

async:false,

success:function(data){

cityData=data;

}

});

vararea =newLArea();

area.init({

'trigger':'#area',// 触发选择控件的文本框,同时选择完毕后name属性输出到该位置

'valueTo':'#areaId',// 选择完毕后id属性输出到该位置

'keys': {

city_id:'city_id',

title:'title'

},

'type':1,// 数据源类型

'data': cityData// 数据源

});

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('错误提示: 没有这种数据源类型');

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);

}

//初始化插件默认值

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);

});

},

//重置节点个数

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容

  • ¥开启¥ 【iAPP实现进入界面执行逐一显】 〖2017-08-25 15:22:14〗 《//首先开一个线程,因...
    小菜c阅读 6,358评论 0 17
  • 在一些电商类的微信小程序中,地址选择这个功能一般是必备的,一般的收货信息都需要有一个能选择省市县的控件,当然也有些...
    第九程序官方阅读 4,054评论 0 6
  • 作者: 惟湛 如何调整ABAP程序的性能(copy) 7、两个内表添加使用批量增加代替逐行不推荐Loop at i...
    SmalltalkVoice阅读 7,438评论 7 18
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,600评论 18 139
  • 我一直在伪装自己,试图掩盖内心那个真实的我。 我想要走出一条路,然后有很多的人跟着我的脚步。 人生就像是电影中的蒙...
    懒妹z阅读 115评论 0 0