移动端省市区三级联动选择器
来源:互联网 发布:广州服装开单软件 编辑:程序博客网 时间:2024/06/06 03:10
移动端项目中遇到三级联动的问题,网上查了很多资料,都是依赖各种插件,或者晦涩难于理解。于是,自己决定写一个出来。 当然,没有用到别的插件类库,也没有用ajax。写完这个小demo也学到不少,现在分享给大家代码。因为代码较多,我就不一个个解释了,源码里面添加了很多注释。 为了便于大家使用,我将html精简了许多。
<!DOCTYPE html>
1<html lang="en">
2<head>
3<meta charset="UTF-8">
4<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
5 <meta name="apple-mobile-web-app-capable" content="yes">
6<title>三级联动</title>
7<link rel="stylesheet" href="index.css">
8</head>
9<body>
10<div class="select">
11请选择区域
12</div>
13<script src="city.js"></script>
14<script src="index.js"></script>
15</body>
16</html>
至于三级联动的数据,我重新定义了一个js文件,在文件中创建了一个json对象,复制了服务器的三级联动的数据过来。 下面是JavaScript代码
0(function(){
1 2var sel = document.querySelector('.select'),
3createDivFlag = true;
4windowHeight = window.screen.availHeight,
5startYFlag = 0;
6 7var div,cur,province,city,county,ok,resut,oneNum,twoNum,threeNum,touchFlag,
8touchOn = true,
9touchStop = true,
10tochBegin = true;
11 12//判断是否能打开
13sel.addEventListener('touchend',function(){
14 15createDivFlag && createDiv();
16 17})
18 19//开始生成盒子
20function createDiv(){
21 22//判断避免重复生成
23if(!div){
24div = document.createElement('div'),
25cur = document.createElement('div'),
26ok = document.createElement('div'),
27resut = document.createElement('div'),
28province = document.createElement('div'),
29city = document.createElement('div'),
30county = document.createElement('div');
31 32div.className = 'win';
33cur.className = 'current';
34ok.className = 'ok';
35resut.className = 'resut';
36province.className = 'province';
37city.className = 'city';
38county.className = 'county';
39 40ok.innerHTML = '完成';
41resut.innerHTML = '取消';
42 43//赋值translate
44province.style.transform = 'translateY(80px)';
45city.style.transform = 'translateY(80px)';
46county.style.transform = 'translateY(80px)';
47//给三个盒子绑定滑动事件
48touchGo([province,city,county]);
49div.appendChild(cur);
50div.appendChild(ok);
51div.appendChild(resut);
52div.appendChild(province);
53div.appendChild(city);
54div.appendChild(county);
55document.body.appendChild(div);
56}
57 58 59//填充数据
60fillIn(province,city,county);
61 62 63setTimeout(function(){
64div.style.transform = 'translateY(-200px)';
65},0);
66 67//确认选择
68ok.addEventListener('touchend',function(){
69 70var one = province.querySelectorAll('span')[oneNum],
71two = city.querySelectorAll('span')[twoNum] || null,
72three = county.querySelectorAll('span')[threeNum] || null,
73selId,
74oneHtml,
75twoHtml,
76threeHtml;
77 78oneHtml = one.innerHTML || '';
79twoHtml = two ? two.innerHTML : '';
80threeHtml = three ? three.innerHTML : '';
81 82sel.innerHTML = oneHtml + twoHtml + threeHtml;
83 84 85oneNodeValue = one ? one.attributes['data-id'].nodeValue : '';
86twoNodeValue = two ? two.attributes['data-id'].nodeValue : '';
87threeNodeValue = three ? three.attributes['data-id'].nodeValue : '';
88selId = oneNodeValue + twoNodeValue + threeNodeValue + '';
89 90sel.setAttribute('data-id',selId);
91 92div.style.transform = 'translateY(0)';
93 94createDivFlag = true;
95 96})
97 98//取消选择
99resut.addEventListener('touchend',function(){
100 101div.style.transform = 'translateY(0)';
102 103createDivFlag = true;
104 105})
106 107createDivFlag = false;
108 109}
110 111 112 113//给三级菜单填充内容
114function fillIn(province,city,county){
115var proStart,cityStart;
116 117//先将内容清空,避免后面累加
118province.innerHTML = '';
119city.innerHTML = '';
120county.innerHTML = '';
121 122//初始化位置
123for(k in region.p['000000']){
124var span = document.createElement('span');
125span.setAttribute("data-id",k);
126span.innerHTML = region.p['000000'][k];
127province.appendChild(span);
128}
129 130proStart = province.querySelector('span').attributes['data-id'].nodeValue;
131 132cityBegin(proStart,city);
133 134cityStart = city.querySelector('span').attributes['data-id'].nodeValue;
135 136countyBegin(cityStart,county);
137 138//初始化时自动先获取一遍初始值
139for(var i = 0; i < arguments.length; i += 1){
140 141//判断第二次打开,是否需要渲染二三级
142if(arguments[i].querySelector('span')){
143 144selectCity(arguments[i]);
145 146}
147}
148 149}
150 151//二级内容
152function cityBegin(proStart,city){
153var flag = true;
154 155if(region.c[proStart]){
156 157for(n in region.c[proStart]){
158var span = document.createElement('span');
159span.setAttribute('data-id',n);
160span.innerHTML = region.c[proStart][n];
161city.appendChild(span);
162}
163 164}else{
165flag = false;
166}
167 168return flag;
169 170}
171 172 173//三级内容
174function countyBegin(cityStart,county){
175for(j in region.d[cityStart]){
176var span = document.createElement('span');
177span.setAttribute('data-id',j);
178span.innerHTML = region.d[cityStart][j];
179county.appendChild(span);
180}
181}
182 183 184//为三级菜单绑定拓展事件
185function touchGo(objArr){
186 187for(var i = 0; i < objArr.length; i += 1){
188 189actionSwiper(objArr[i]);
190 191}
192 193//为三级菜单绑定事件
194function actionSwiper(obj){
195 196var startPosition,movePosition,endPosition,deletaY,transY;
197 198//tochBegin,touchOn,touchStop;三个状态判断
199obj.addEventListener('touchstart',function(event){
200if(touchStop){
201touchStop = false;
202var touch = event.touches[0];
203startPosition = {
204x : touch.pageX,
205y : touch.pageY
206}
207transY = Number(translateXY(obj));
208objHeight = obj.offsetHeight;
209tochBegin = true;
210}
211 212})
213 214 215//80 为两个span的高度,初始化时,距离上方80px
216//200 为自定义select的高度。
217obj.addEventListener('touchmove',function(event){
218 219if(tochBegin){
220 221touchOn = true;
222 223var touch = event.touches[0];
224 225movePosition = {
226x : touch.pageX,
227y : touch.pageY
228};
229 230deletaY = movePosition.y - startPosition.y + transY;
231 232//向上划上限
233//deletaY = deletaY > -objHeight - 80 + 200 ? deletaY : -objHeight - 80 + 200;
234deletaY = deletaY > -objHeight + 120 ? deletaY : -objHeight + 120;
235 236//向下滑下限
237deletaY = deletaY > 80 ? 80 : deletaY;
238 239 240obj.style.transform = 'translateY('+ deletaY +'px)';
241 242//禁止浏览器默认黑色背景出现
243event.preventDefault();
244 245 246}
247 248})
249 250obj.addEventListener('touchend',function(){
251 252if(touchOn){
253 254touchStop = true;
255 256var touch = event.changedTouches[0];
257 258endPosition = {
259x : touch.pageX,
260y : touch.pageY
261};
262 263setTimeout(function(){
264objTouchEnd(obj);
265},100);
266 267}
268 269})
270 271//滑动结束后处理函数
272function objTouchEnd(obj){
273 274var objTranslateY = parseInt(Number(translateXY(obj))),
275objType = '',
276timer = null;
277 278if(endPosition.y - startPosition.y > 0){
279objType = 'down';
280}else{
281objType = 'up';
282}
283 284timer = setInterval(function(){
285 286 287if(objType == 'up'){
288if(Number(translateXY(obj)) % 40 != 0){
289objTranslateY -= 1;
290}
291}
292 293if(objType == 'down'){
294if(Number(translateXY(obj)) % 40 != 0){
295objTranslateY += 1;
296}
297}
298 299obj.style.transform = 'translateY('+ objTranslateY +'px)';
300 301if(Number(translateXY(obj)) % 40 == 0){
302
303clearInterval(timer);
304timer = null;
305 306tochBegin = false;
307 308//确定选择
309selectCity(obj);
310 311}
312 313 314},20);
315 316 317 318}
319 320}
321 322}
323 324 325//获取设置选项
326function selectCity(obj){
327//80+80=160 Y为80 的时候是第一个
328var objTranslateY = Number(translateXY(obj)),
329one,
330oneId,
331onText,
332two,
333twoId,
334twoText,
335three,
336threeId,
337threeText,
338twoGoThree;
339 340if(obj == province){
341 342oneNum = Math.abs((objTranslateY + 80 - 160) / 40);
343 344//获取序号
345one = province.querySelectorAll('span')[oneNum];
346 347//获取自定义属性值
348oneId = one.attributes['data-id'].nodeValue;
349 350//清空下一级内容
351city.innerHTML = '';
352 353//重置下一级translateY
354city.style.transform = 'translateY(80px)';
355 356//重置第三级translateY
357county.style.transform = 'translateY(80px)';
358 359//填充下一级内容
360twoGoThree = cityBegin(oneId,city);
361 362//清空第三项
363county.innerHTML = '';
364 365//默认第三级默认第二级第一项
366if(twoGoThree){
367countyBegin(city.querySelector('span').attributes['data-id'].nodeValue,county);
368}
369 370}
371 372if(obj == city){
373 374twoNum = Math.abs((objTranslateY + 80 - 160) / 40);
375 376//获取序号
377two = city.querySelectorAll('span')[twoNum];
378 379//获取选中选项自定义属性值
380twoId = two.attributes['data-id'].nodeValue;
381 382//清空第三项值
383county.innerHTML = '';
384 385//重置第三项translateY
386county.style.transform = 'translateY(80px)';
387 388//填充第三项
389if(twoId){
390countyBegin(twoId,county);
391}
392 393}
394 395if(obj == county){
396 397threeNum = Math.abs((objTranslateY + 80 - 160) / 40);
398 399//获取序号
400three = county.querySelectorAll('span')[threeNum];
401 402//获取选中选项自定义属性值
403threeId = three.attributes['data-id'].nodeValue;
404 405}
406 407}
408 409//获取translateY值
410function translateXY(obj){
411 var beeTransform = obj.style.transform.replace(/\s/g,'');
412 beeTransform = beeTransform.replace('translateY','');
413 beeTransform = beeTransform.slice(1,-1);
414 beeTransform = beeTransform.replace('px','');
415 return beeTransform;
416}
417 418})()
阅读全文
0 0
- 移动端省市区三级联动选择器
- Android 地址选择器,实现省市区三级联动
- Android_全国省市区-三级联动 时间选择器
- Android 地址选择器,实现省市区三级联动
- 一秒集成省市区三级联动选择器
- 手机端省市区三级联动
- sencha Touch 省市区三级联动滚轮效果选择器
- 一秒集成 省市区三级联动选择器-CityPickerView
- 省市区三级联动城市选择器(仿iOS滚轮实现)
- 使用pickerview实现(省市区)地址选择器的三级联动
- 一秒集成 省市区三级联动选择器-CityPickerView
- 三级联动省市区城市选择器v2.1.0新版本发布
- 三级联动省市区城市地区选择器v2.1.0新版本发布
- js省市区三级联动
- 省市区三级联动
- 省市区三级联动
- 省市区三级异步联动
- PHP、省市区三级联动
- select/option标签动态获取默认值的判断
- centos7 下 安装 Marria 版数据库
- JavaWeb:报错信息The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path
- android xml 解析
- tp 极光推送
- 移动端省市区三级联动选择器
- hbase启动不了,端口占用问题
- 运用Kubernetes进行分布式负载测试
- 程序员就职需要准备或者注意的事情
- Thinkphp中用sql语句插入数据时,虽然成功插入但是报错
- 你可能不知道的 Mac 技巧
- Android BLE 蓝牙低功耗教程,中央BluetoothGatt和周边BluetoothGattServer的实现
- 面试题15连表中倒数第k个结点
- Win32获取屏幕可用尺寸/获取桌面可用区域 (即除去任务栏的区域)