在淘宝旅行上看到的城市选择效果,感觉还不错,就自己的理解重新实现一遍,先看效果(有人说IE9下面有BUG,LZ用的是落后的XP,居然装不上IE9,去公司在搞搞好了),然后再细说实现原理,支持鼠标上下键选择城市,支持直接输入城市名称,拼音首字母,全拼,支持IE6遮盖SELECT,压缩后12K。
实现的步骤:
一、先用一定的格式罗列出控件所需要的城市以及拼音等,我这里是按照如下格式罗列成一个数组, 如果需要增加城市,直接增加在数组里面即可:
城市我是一个一个手打的。。。
['北京|beijing|bj','上海|shanghai|sh', '重庆|chongqing|cq']
二、因为控件的城市分组按好几类划分,比如:按首字母HOT 、ABCDEFH 、 IJKLMNOP 、 QRSTUVWXYZ 四组划分,
而划分了四组后又按照了首字母划分,所以我用正则表达式和循环把数组重新格式化为一个分组对象,热门城市取前16条。
对象格式如下:
{HOT:{hot:[]},ABCDEFGH:{a:[1,2,3],b:[1,2,3]},IJKLMNOP:{i:[1.2.3],j:[1,2,3]},QRSTUVWXYZ:{}}
所用代码如下:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 |
/* * * 格式化城市数组为对象oCity,按照a-h,i-p,q-z,hot热门城市分组: * {HOT:{hot:[]},ABCDEFGH:{a:[1,2,3],b:[1,2,3]},IJKLMNOP:{i:[1.2.3],j:[1,2,3]},QRSTUVWXYZ:{}} * */ ( function () { var citys = Vcity.allCity, match, letter, regEx = Vcity.regEx, reg2 = /^[a-h]$/i, reg3 = /^[i-p]$/i, reg4 = /^[q-z]$/i; if (!Vcity.oCity) { Vcity.oCity = {hot:{},ABCDEFGH:{}, IJKLMNOP:{}, QRSTUVWXYZ:{}}; //console.log(citys.length); for ( var i = 0, n = citys.length; i < n; i++) { match = regEx.exec(citys[i]); letter = match[3].toUpperCase(); if (reg2.test(letter)) { if (!Vcity.oCity.ABCDEFGH[letter]) Vcity.oCity.ABCDEFGH[letter] = []; Vcity.oCity.ABCDEFGH[letter].push(match[1]); } else if (reg3.test(letter)) { if (!Vcity.oCity.IJKLMNOP[letter]) Vcity.oCity.IJKLMNOP[letter] = []; Vcity.oCity.IJKLMNOP[letter].push(match[1]); } else if (reg4.test(letter)) { if (!Vcity.oCity.QRSTUVWXYZ[letter]) Vcity.oCity.QRSTUVWXYZ[letter] = []; Vcity.oCity.QRSTUVWXYZ[letter].push(match[1]); } /* 热门城市 前16条 */ if (i<16){ if (!Vcity.oCity.hot[ 'hot' ]) Vcity.oCity.hot[ 'hot' ] = []; Vcity.oCity.hot[ 'hot' ].push(match[1]); } } } })(); |
三、然后先照着淘宝旅行里面的样子弄出HTML与CSS;这里略过。
四、然后开始建立CitySelector构造函数,根据城市对象,构建生成DOM对象,在按照相应的事件触发。在生成相应的按照A\B\C\D……分组的时候遇到一个
关于排序的问题,我的对象格式是这样的ABCDEFGH:{a:[1,2,3],b:[1,2,3],c:[1,2,3]},里面的小数组要按照字母的顺序排序,但是我用for……in循环生成
出来是乱的,咨询了群里的高人后,处理方法如下:这里单独把KEY拿出来组成一个数组,然后排序后,在根据数组的值作为KEY值,来读取对象!
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 |
sortKey=[]; for (ckey in oCity[key]){ sortKey.push(ckey); // ckey按照ABCDEDG顺序排序 sortKey.sort(); } for ( var j=0,k = sortKey.length;j odl = document.createElement( 'dl' ); odt = document.createElement( 'dt' ); odd = document.createElement( 'dd' ); odt.innerHTML = sortKey[j] == 'hot' ? ' ' :sortKey[j]; odda = []; for ( var i=0,n=oCity[key][sortKey[j]].length;i odda.push(str); } |
五、鼠标上下键移动选择城市的处理方法:在城市弹出后记录一个this.count = 0;然后再获取上下键的按键事件中分别对count值加一或者减一,
当然count的最大值不能大于筛选出来的城市数组的长度,超过长度后归0,小于0后赋值最大值,然后把this.count的值,来作为数组的标获取相应的城市项:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 |
switch (keycode){ case 40: //向下箭头↓ this .count++; if ( this .count > len-1) this .count = 0; for ( var i=0;i Vcity._m.removeClass( 'on' ,lis[i]); } Vcity._m.addClass( 'on' ,lis[ this .count]); break ; case 38: //向上箭头↑ this .count--; if ( this .count<0) this .count = len-1; for (i=0;i Vcity._m.removeClass( 'on' ,lis[i]); } Vcity._m.addClass( 'on' ,lis[ this .count]); break ; case 13: // enter键 this .input.value = Vcity.regExChiese.exec(lis[ this .count].innerHTML)[0]; Vcity._m.addClass( 'hide' , this .ul); Vcity._m.addClass( 'hide' , this .ul); /* IE6 */ Vcity._m.addClass( 'hide' , this .myIframe); break ; default : break ; } |
六、IE中对SELECT的遮挡也是一个增加代码的地方,因为城市弹出框的大小是变化的,然后下拉的城市列也是根据筛选出来的值而变化,所以得每操作一个变化的地方的时候就重新给iframe设置长度和宽度,苦逼的处理方法啊,所以就多了这样一个方法,然后在改变尺寸的时候,应用一下就可以了。
?
1
2
3
4
5
6 |
/* IE6的改变遮罩SELECT 的 IFRAME尺寸大小 */ changeIframe:function(){ if (! this .isIE6) return ; this .myIframe.style.width = this .rootDiv.offsetWidth + 'px' ; this .myIframe.style.height = this .rootDiv.offsetHeight + 'px' ; } |
7、弹出框的取消问题,这个问题最开始我是设置document的click事件关闭层,然后再弹出的层上阻止click事件的冒泡,但是这样两个层有同时出现的可能,
?
1
2
3
4
5
6
7
8
9
10 |
// 设置点击文档隐藏弹出的城市选择框 Vcity._m.on(document, 'click' , function (event) { event = Vcity._m.getEvent(event); var target = Vcity._m.getTarget(event); if (target == that.input) return false ; //console.log(target.className); if (that.cityBox)Vcity._m.addClass( 'hide' , that.cityBox); if (that.ul)Vcity._m.addClass( 'hide' , that.ul); if (that.myIframe)Vcity._m.addClass( 'hide' ,that.myIframe); }); |
8、输入框输入拼音或者文字或者拼音首字母筛选城市,这个就是直接用正则表达式在最开始的数组里面筛选数据即可:
?
1
2
3
4
5
6
7
8
9
10
11
12
13 |
var reg = new RegExp( "^" + value + "|\\|" + value, 'gi' ); var searchResult = []; for ( var i = 0, n = Vcity.allCity.length; i < n; i++) { if (reg.test(Vcity.allCity[i])) { var match = Vcity.regEx.exec(Vcity.allCity[i]); if (searchResult.length !== 0) { str = '
+ match[1] + '' + match[2] + '' ; } else { str = '
+ match[1] + '' + match[2] + '' ; } searchResult.push(str); } } |
然后总的JS代码如下:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515 |
/* * * ---------------------------------------- * * 城市选择组件 v1.0 * Author: VVG * QQ: 83816819 * Mail: mysheller@163.com * ---------------------------------------- * * Date: 2012-07-10 * ---------------------------------------- * * */ /* * * 全局空间 Vcity * */ var Vcity = {}; /* * * 静态方法集 * @name _m * */ Vcity._m = { /* 选择元素 */ $: function (arg, context) { var tagAll, n, eles = [], i, sub = arg.substring(1); context = context || document; if ( typeof arg == 'string' ) { switch (arg.charAt(0)) { case '#' : return document.getElementById(sub); break ; case '.' : if (context.getElementsByClassName) return context.getElementsByClassName(sub); tagAll = Vcity._m.$( '*' , context); n = tagAll.length; for (i = 0; i < n; i++) { if (tagAll[i].className.indexOf(sub) > -1) eles.push(tagAll[i]); } return eles; break ; default : return context.getElementsByTagName(arg); break ; } } }, /* 绑定事件 */ on: function (node, type, handler) { node.addEventListener ? node.addEventListener(type, handler, false ) : node.attachEvent( 'on' + type, handler); }, /* 获取事件 */ getEvent: function (event){ return event || window.event; }, /* 获取事件目标 */ getTarget: function (event){ return event.target || event.srcElement; }, /* 获取元素位置 */ getPos: function (node) { var scrollx = document.documentElement.scrollLeft || document.body.scrollLeft, scrollt = document.documentElement.scrollTop || document.body.scrollTop; var pos = node.getBoundingClientRect(); return {top:pos.top + scrollt, right:pos.right + scrollx, bottom:pos.bottom + scrollt, left:pos.left + scrollx } }, /* 添加样式名 */ addClass: function (c, node) { if (!node) return ; node.className = Vcity._m.hasClass(c,node) ? node.className : node.className + ' ' + c ; }, /* 移除样式名 */ removeClass: function (c, node) { var reg = new RegExp( "(^|\\s+)" + c + "(\\s+|$)" , "g" ); if (!Vcity._m.hasClass(c,node)) return ; node.className = reg.test(node.className) ? node.className.replace(reg, '' ) : node.className; }, /* 是否含有CLASS */ hasClass: function (c, node) { if (!node || !node.className) return false ; return node.className.indexOf(c)>-1; }, /* 阻止冒泡 */ stopPropagation: function (event) { event = event || window.event; event.stopPropagation ? event.stopPropagation() : event.cancelBubble = true ; }, /* 去除两端空格 */ trim: function (str) { return str.replace(/^\s+|\s+$/g, '' ); } }; /* 所有城市数据,可以按照格式自行添加(北京|beijing|bj),前16条为热门城市 */ Vcity.allCity = [ '北京|beijing|bj' , '上海|shanghai|sh' , '重庆|chongqing|cq' , '深圳|shenzhen|sz' , '广州|guangzhou|gz' , '杭州|hangzhou|hz' , '南京|nanjing|nj' , '苏州|shuzhou|sz' , '天津|tianjin|tj' , '成都|chengdu|cd' , '南昌|nanchang|nc' , '三亚|sanya|sy' , '青岛|qingdao|qd' , '厦门|xiamen|xm' , '西安|xian|xa' , '长沙|changsha|cs' , '合肥|hefei|hf' , '西藏|xizang|xz' , '内蒙古|neimenggu|nmg' , '安庆|anqing|aq' , '阿泰勒|ataile|atl' , '安康|ankang|ak' , '阿克苏|akesu|aks' , '包头|baotou|bt' , '北海|beihai|bh' , '百色|baise|bs' , '保山|baoshan|bs' , '长治|changzhi|cz' , '长春|changchun|cc' , '常州|changzhou|cz' , '昌都|changdu|cd' , '朝阳|chaoyang|cy' , '常德|changde|cd' , '长白山|changbaishan|cbs' , '赤峰|chifeng|cf' , '大同|datong|dt' , '大连|dalian|dl' , '达县|daxian|dx' , '东营|dongying|dy' , '大庆|daqing|dq' , '丹东|dandong|dd' , '大理|dali|dl' , '敦煌|dunhuang|dh' , '鄂尔多斯|eerduosi|eeds' , '恩施|enshi|es' , '福州|fuzhou|fz' , '阜阳|fuyang|fy' , '贵阳|guiyang|gy' , '桂林|guilin|gl' , '广元|guangyuan|gy' , '格尔木|geermu|gem' , '呼和浩特|huhehaote|hhht' , '哈密|hami|hm' , '黑河|heihe|hh' , '海拉尔|hailaer|hle' , '哈尔滨|haerbin|heb' , '海口|haikou|hk' , '黄山|huangshan|hs' , '邯郸|handan|hd' , '汉中|hanzhong|hz' , '和田|hetian|ht' , '晋江|jinjiang|jj' , '锦州|jinzhou|jz' , '景德镇|jingdezhen|jdz' , '嘉峪关|jiayuguan|jyg' , '井冈山|jinggangshan|jgs' , '济宁|jining|jn' , '九江|jiujiang|jj' , '佳木斯|jiamusi|jms' , '济南|jinan|jn' , '喀什|kashi|ks' , '昆明|kunming|km' , '康定|kangding|kd' , '克拉玛依|kelamayi|klmy' , '库尔勒|kuerle|kel' , '库车|kuche|kc' , '兰州|lanzhou|lz' , '洛阳|luoyang|ly' , '丽江|lijiang|lj' , '林芝|linzhi|lz' , '柳州|liuzhou|lz' , '泸州|luzhou|lz' , '连云港|lianyungang|lyg' , '黎平|liping|lp' , '连成|liancheng|lc' , '拉萨|lasa|ls' , '临沧|lincang|lc' , '临沂|linyi|ly' , '芒市|mangshi|ms' , '牡丹江|mudanjiang|mdj' , '满洲里|manzhouli|mzl' , '绵阳|mianyang|my' , '梅县|meixian|mx' , '漠河|mohe|mh' , '南充|nanchong|nc' , '南宁|nanning|nn' , '南阳|nanyang|ny' , '南通|nantong|nt' , '那拉提|nalati|nlt' , '宁波|ningbo|nb' , '攀枝花|panzhihua|pzh' , '衢州|quzhou|qz' , '秦皇岛|qinhuangdao|qhd' , '庆阳|qingyang|qy' , '齐齐哈尔|qiqihaer|qqhe' , '石家庄|shijiazhuang|sjz' , '沈阳|shenyang|sy' , '思茅|simao|sm' , '铜仁|tongren|tr' , '塔城|tacheng|tc' , '腾冲|tengchong|tc' , '台州|taizhou|tz' , '通辽|tongliao|tl' , '太原|taiyuan|ty' , '威海|weihai|wh' , '梧州|wuzhou|wz' , '文山|wenshan|ws' , '无锡|wuxi|wx' , '潍坊|weifang|wf' , '武夷山|wuyishan|wys' , '乌兰浩特|wulanhaote|wlht' , '温州|wenzhou|wz' , '乌鲁木齐|wulumuqi|wlmq' , '万州|wanzhou|wz' , '乌海|wuhai|wh' , '兴义|xingyi|xy' , '西昌|xichang|xc' , '襄樊|xiangfan|xf' , '西宁|xining|xn' , '锡林浩特|xilinhaote|xlht' , '西双版纳|xishuangbanna|xsbn' , '徐州|xuzhou|xz' , '义乌|yiwu|yw' , '永州|yongzhou|yz' , '榆林|yulin|yl' , '延安|yanan|ya' , '运城|yuncheng|yc' , '烟台|yantai|yt' , '银川|yinchuan|yc' , '宜昌|yichang|yc' , '宜宾|yibin|yb' , '盐城|yancheng|yc' , '延吉|yanji|yj' , '玉树|yushu|ys' , '伊宁|yining|yn' , '珠海|zhuhai|zh' , '昭通|zhaotong|zt' , '张家界|zhangjiajie|zjj' , '舟山|zhoushan|zs' , '郑州|zhengzhou|zz' , '中卫|zhongwei|zw' , '芷江|zhijiang|zj' , '湛江|zhanjiang|zj' ]; /* 正则表达式 筛选中文城市名、拼音、首字母 */ Vcity.regEx = /^([\u4E00-\u9FA5\uf900-\ufa2d]+)\|(\w+)\|(\w)\w*$/i; Vcity.regExChiese = /([\u4E00-\u9FA5\uf900-\ufa2d]+)/; /* * * 格式化城市数组为对象oCity,按照a-h,i-p,q-z,hot热门城市分组: * {HOT:{hot:[]},ABCDEFGH:{a:[1,2,3],b:[1,2,3]},IJKLMNOP:{i:[1.2.3],j:[1,2,3]},QRSTUVWXYZ:{}} * */ ( function () { var citys = Vcity.allCity, match, letter, regEx = Vcity.regEx, reg2 = /^[a-h]$/i, reg3 = /^[i-p]$/i, reg4 = /^[q-z]$/i; if (!Vcity.oCity) { Vcity.oCity = {hot:{},ABCDEFGH:{}, IJKLMNOP:{}, QRSTUVWXYZ:{}}; //console.log(citys.length); for ( var i = 0, n = citys.length; i < n; i++) { match = regEx.exec(citys[i]); letter = match[3].toUpperCase(); if (reg2.test(letter)) { if (!Vcity.oCity.ABCDEFGH[letter]) Vcity.oCity.ABCDEFGH[letter] = []; Vcity.oCity.ABCDEFGH[letter].push(match[1]); } else if (reg3.test(letter)) { if (!Vcity.oCity.IJKLMNOP[letter]) Vcity.oCity.IJKLMNOP[letter] = []; Vcity.oCity.IJKLMNOP[letter].push(match[1]); } else if (reg4.test(letter)) { if (!Vcity.oCity.QRSTUVWXYZ[letter]) Vcity.oCity.QRSTUVWXYZ[letter] = []; Vcity.oCity.QRSTUVWXYZ[letter].push(match[1]); } /* 热门城市 前16条 */ if (i<16){ if (!Vcity.oCity.hot[ 'hot' ]) Vcity.oCity.hot[ 'hot' ] = []; Vcity.oCity.hot[ 'hot' ].push(match[1]); } } } })(); /* 城市HTML模板 */ Vcity._template = [ '
, '
, '
, '
, '
, '
, '
]; /* * * 城市控件构造函数 * @CitySelector * */ Vcity.CitySelector = function () { this .initialize.apply( this , arguments); }; Vcity.CitySelector.prototype = { constructor:Vcity.CitySelector, /* 初始化 */ initialize : function (options) { var input = options.input; this .input = Vcity._m.$( '#' + input); this .inputEvent(); }, /* * * @createWarp * 创建城市BOX HTML 框架 * */ createWarp: function (){ var inputPos = Vcity._m.getPos( this .input); var div = this .rootDiv = document.createElement( 'div' ); var that = this ; // 设置DIV阻止冒泡 Vcity._m.on( this .rootDiv, 'click' , function (event){ Vcity._m.stopPropagation(event); }); // 设置点击文档隐藏弹出的城市选择框 Vcity._m.on(document, 'click' , function (event) { event = Vcity._m.getEvent(event); var target = Vcity._m.getTarget(event); if (target == that.input) return false ; //console.log(target.className); if (that.cityBox)Vcity._m.addClass( 'hide' , that.cityBox); if (that.ul)Vcity._m.addClass( 'hide' , that.ul); if (that.myIframe)Vcity._m.addClass( 'hide' ,that.myIframe); }); div.className = 'citySelector' ; div.style.position = 'absolute' ; div.style.left = inputPos.left + 'px' ; div.style.top = inputPos.bottom + 'px' ; div.style.zIndex = 999999; // 判断是否IE6,如果是IE6需要添加iframe才能遮住SELECT框 var isIe = (document.all) ? true : false ; var isIE6 = this .isIE6 = isIe && !window.XMLHttpRequest; if (isIE6){ var myIframe = this .myIframe = document.createElement( 'iframe' ); myIframe.frameborder = '0' ; myIframe.src = 'about:blank' ; myIframe.style.position = 'absolute' ; myIframe.style.zIndex = '-1' ; this .rootDiv.appendChild( this .myIframe); } var childdiv = this .cityBox = document.createElement( 'div' ); childdiv.className = 'cityBox' ; childdiv.id = 'cityBox' ; childdiv.innerHTML = Vcity._template.join( '' ); var hotCity = this .hotCity = document.createElement( 'div' ); hotCity.className = 'hotCity' ; childdiv.appendChild(hotCity); div.appendChild(childdiv); this .createHotCity(); }, /* * * @createHotCity * TAB下面DIV:hot,a-h,i-p,q-z 分类HTML生成,DOM操作 * {HOT:{hot:[]},ABCDEFGH:{a:[1,2,3],b:[1,2,3]},IJKLMNOP:{},QRSTUVWXYZ:{}} **/ createHotCity: function (){ var odiv,odl,odt,odd,odda=[],str,key,ckey,sortKey,regEx = Vcity.regEx, oCity = Vcity.oCity; for (key in oCity){ odiv = this [key] = document.createElement( 'div' ); // 先设置全部隐藏hide odiv.className = key + ' ' + 'cityTab hide' ; sortKey=[]; for (ckey in oCity[key]){ sortKey.push(ckey); // ckey按照ABCDEDG顺序排序 sortKey.sort(); } for ( var j=0,k = sortKey.length;j odl = document.createElement( 'dl' ); odt = document.createElement( 'dt' ); odd = document.createElement( 'dd' ); odt.innerHTML = sortKey[j] == 'hot' ? ' ' :sortKey[j]; odda = []; for ( var i=0,n=oCity[key][sortKey[j]].length;i odda.push(str); } odd.innerHTML = odda.join( '' ); odl.appendChild(odt); odl.appendChild(odd); odiv.appendChild(odl); } // 移除热门城市的隐藏CSS Vcity._m.removeClass( 'hide' , this .hot); this .hotCity.appendChild(odiv); } document.body.appendChild( this .rootDiv); /* IE6 */ this .changeIframe(); this .tabChange(); this .linkEvent(); }, /* * * tab按字母顺序切换 * @ tabChange * */ tabChange: function (){ var lis = Vcity._m.$( 'li' , this .cityBox); var divs = Vcity._m.$( 'div' , this .hotCity); var that = this ; for ( var i=0,n=lis.length;i lis[i].index = i; lis[i].onclick = function (){ for ( var j=0;j Vcity._m.removeClass( 'on' ,lis[j]); Vcity._m.addClass( 'hide' ,divs[j]); } Vcity._m.addClass( 'on' , this ); Vcity._m.removeClass( 'hide' ,divs[ this .index]); /* IE6 改变TAB的时候 改变Iframe 大小*/ that.changeIframe(); }; } }, /* * * 城市LINK事件 * @linkEvent * */ linkEvent: function (){ var links = Vcity._m.$( 'a' , this .hotCity); var that = this ; for ( var i=0,n=links.length;i links[i].onclick = function (){ that.input.value = this .innerHTML; Vcity._m.addClass( 'hide' ,that.cityBox); /* 点击城市名的时候隐藏myIframe */ Vcity._m.addClass( 'hide' ,that.myIframe); } } }, /* * * INPUT城市输入框事件 * @inputEvent * */ inputEvent: function (){ var that = this ; Vcity._m.on( this .input, 'click' , function (event){ event = event || window.event; if (!that.cityBox){ that.createWarp(); } else if (!!that.cityBox && Vcity._m.hasClass( 'hide' ,that.cityBox)){ // slideul 不存在或者 slideul存在但是是隐藏的时候 两者不能共存 if (!that.ul || (that.ul && Vcity._m.hasClass( 'hide' ,that.ul))){ Vcity._m.removeClass( 'hide' ,that.cityBox); /* IE6 移除iframe 的hide 样式 */ //alert('click'); Vcity._m.removeClass( 'hide' ,that.myIframe); that.changeIframe(); } } }); Vcity._m.on( this .input, 'focus' , function (){ that.input.select(); if (that.input.value == '城市名' ) that.input.value = '' ; }); Vcity._m.on( this .input, 'blur' , function (){ if (that.input.value == '' ) that.input.value = '城市名' ; }); Vcity._m.on( this .input, 'keyup' , function (event){ event = event || window.event; var keycode = event.keyCode; Vcity._m.addClass( 'hide' ,that.cityBox); that.createUl(); /* 移除iframe 的hide 样式 */ Vcity._m.removeClass( 'hide' ,that.myIframe); // 下拉菜单显示的时候捕捉按键事件 if (that.ul && !Vcity._m.hasClass( 'hide' ,that.ul) && !that.isEmpty){ that.KeyboardEvent(event,keycode); } }); }, /* * * 生成下拉选择列表 * @ createUl * */ createUl: function () { //console.log('createUL'); var str; var value = Vcity._m.trim( this .input.value); // 当value不等于空的时候执行 if (value !== '' ) { var reg = new RegExp( "^" + value + "|\\|" + value, 'gi' ); var searchResult = []; for ( var i = 0, n = Vcity.allCity.length; i < n; i++) { if (reg.test(Vcity.allCity[i])) { var match = Vcity.regEx.exec(Vcity.allCity[i]); if (searchResult.length !== 0) { str = '
+ match[1] + '' + match[2] + '' ; } else { str = '
+ match[1] + '' + match[2] + '' ; } searchResult.push(str); } } this .isEmpty = false ; // 如果搜索数据为空 if (searchResult.length == 0) { this .isEmpty = true ; str = '
+ value + '"' ; searchResult.push(str); } // 如果slideul不存在则添加ul if (! this .ul) { var ul = this .ul = document.createElement( 'ul' ); ul.className = 'cityslide' ; this .rootDiv && this .rootDiv.appendChild(ul); // 记录按键次数,方向键 this .count = 0; } else if ( this .ul && Vcity._m.hasClass( 'hide' , this .ul)) { this .count = 0; Vcity._m.removeClass( 'hide' , this .ul); } this .ul.innerHTML = searchResult.join( '' ); /* IE6 */ this .changeIframe(); // 绑定Li事件 this .liEvent(); } else { Vcity._m.addClass( 'hide' , this .ul); Vcity._m.removeClass( 'hide' , this .cityBox); Vcity._m.removeClass( 'hide' , this .myIframe); this .changeIframe(); } }, /* IE6的改变遮罩SELECT 的 IFRAME尺寸大小 */ changeIframe: function (){ if (! this .isIE6) return ; this .myIframe.style.width = this .rootDiv.offsetWidth + 'px' ; this .myIframe.style.height = this .rootDiv.offsetHeight + 'px' ; }, /* * * 特定键盘事件,上、下、Enter键 * @ KeyboardEvent * */ KeyboardEvent: function (event,keycode){ var lis = Vcity._m.$( 'li' , this .ul); var len = lis.length; switch (keycode){ case 40: //向下箭头↓ this .count++; if ( this .count > len-1) this .count = 0; for ( var i=0;i Vcity._m.removeClass( 'on' ,lis[i]); } Vcity._m.addClass( 'on' ,lis[ this .count]); break ; case 38: //向上箭头↑ this .count--; if ( this .count<0) this .count = len-1; for (i=0;i Vcity._m.removeClass( 'on' ,lis[i]); } Vcity._m.addClass( 'on' ,lis[ this .count]); break ; case 13: // enter键 this .input.value = Vcity.regExChiese.exec(lis[ this .count].innerHTML)[0]; Vcity._m.addClass( 'hide' , this .ul); Vcity._m.addClass( 'hide' , this .ul); /* IE6 */ Vcity._m.addClass( 'hide' , this .myIframe); break ; default : break ; } }, /* * * 下拉列表的li事件 * @ liEvent * */ liEvent: function (){ var that = this ; var lis = Vcity._m.$( 'li' , this .ul); for ( var i = 0,n = lis.length;i < n;i++){ Vcity._m.on(lis[i], 'click' , function (event){ event = Vcity._m.getEvent(event); var target = Vcity._m.getTarget(event); that.input.value = Vcity.regExChiese.exec(target.innerHTML)[0]; Vcity._m.addClass( 'hide' ,that.ul); /* IE6 下拉菜单点击事件 */ Vcity._m.addClass( 'hide' ,that.myIframe); }); Vcity._m.on(lis[i], 'mouseover' , function (event){ event = Vcity._m.getEvent(event); var target = Vcity._m.getTarget(event); Vcity._m.addClass( 'on' ,target); }); Vcity._m.on(lis[i], 'mouseout' , function (event){ event = Vcity._m.getEvent(event); var target = Vcity._m.getTarget(event); Vcity._m.removeClass( 'on' ,target); }) } } }; |
以上就是本文的全部内容,希望对大家的学习有所帮助
jsp复习资料汇总
[JSP]2017年1月24日asp教程编程辅导汇总
[ASP]2016年12月2日JSP快速入门教程汇总
[JSP]2016年12月2日jsp基本用法和命令汇总
[JSP]2016年10月3日ASP编码教程:如何实现/使用缓存
[ASP]2015年4月15日