欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

JavaScript实现城市选择控件的效果

程序员文章站 2022-07-12 08:25:28
在淘宝旅行上看到的城市选择效果,感觉还不错,就自己的理解重新实现一遍,先看效果(有人说ie9下面有bug,lz用的是落后的xp,居然装不上ie9,去公司在搞搞好了),然后再...

在淘宝旅行上看到的城市选择效果,感觉还不错,就自己的理解重新实现一遍,先看效果(有人说ie9下面有bug,lz用的是落后的xp,居然装不上ie9,去公司在搞搞好了),然后再细说实现原理,支持鼠标上下键选择城市,支持直接输入城市名称,拼音首字母,全拼,支持ie6遮盖select,压缩后12k。

JavaScript实现城市选择控件的效果

实现的步骤:

一、先用一定的格式罗列出控件所需要的城市以及拼音等,我这里是按照如下格式罗列成一个数组, 如果需要增加城市,直接增加在数组里面即可:

城市我是一个一个手打的。。。

['北京|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:{}}

所用代码如下:

/* * 
 * 格式化城市数组为对象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值,来读取对象!

sortkey=[]; 
   for(ckey in ocity[key]){ 
    sortkey.push(ckey); 
    // ckey按照abcdedg顺序排序 
    sortkey.sort(); 
   } 
   for(var j=0,k = sortkey.length;j<k;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<n;i++){ 
     str = '<a href="#">' + ocity[key][sortkey[j]][i] + '</a>'; 
     odda.push(str); 
    } 

五、鼠标上下键移动选择城市的处理方法:在城市弹出后记录一个this.count = 0;然后再获取上下键的按键事件中分别对count值加一或者减一,

当然count的最大值不能大于筛选出来的城市数组的长度,超过长度后归0,小于0后赋值最大值,然后把this.count的值,来作为数组的标获取相应的城市项:

switch(keycode){ 
   case 40: //向下箭头↓ 
    this.count++; 
    if(this.count > len-1) this.count = 0; 
    for(var i=0;i<len;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<len;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设置长度和宽度,苦逼的处理方法啊,所以就多了这样一个方法,然后在改变尺寸的时候,应用一下就可以了。

/* 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事件的冒泡,但是这样两个层有同时出现的可能,

// 设置点击文档隐藏弹出的城市选择框 
  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、输入框输入拼音或者文字或者拼音首字母筛选城市,这个就是直接用正则表达式在最开始的数组里面筛选数据即可:

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 = '<li><b class="cityname">' + match[1] + '</b><b class="cityspell">' + match[2] + '</b></li>'; 
     } else { 
      str = '<li class="on"><b class="cityname">' + match[1] + '</b><b class="cityspell">' + match[2] + '</b></li>'; 
     } 
     searchresult.push(str); 
    } 
   }

然后总的js代码如下:

/* * 
 * ---------------------------------------- * 
 * 城市选择组件 v1.0 
 * author: vvg 
 * qq: 83816819 
 * mail: mysheller@163.com 
 * http://www.cnblogs.com/nnuf/ 
 * ---------------------------------------- * 
 * 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', '武夷山|*shan|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 = [ 
 '<p class="tip">热门城市(支持汉字/拼音)</p>', 
 '<ul>', 
 '<li class="on">热门城市</li>', 
 '<li>abcdefgh</li>', 
 '<li>ijklmnop</li>', 
 '<li>qrstuvwxyz</li>', 
 '</ul>' 
]; 
 
/* * 
 * 城市控件构造函数 
 * @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<k;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<n;i++){ 
     str = '<a href="javascript:">' + ocity[key][sortkey[j]][i] + '</a>'; 
     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<n;i++){ 
   lis[i].index = i; 
   lis[i].onclick = function(){ 
    for(var j=0;j<n;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<n;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 = '<li><b class="cityname">' + match[1] + '</b><b class="cityspell">' + match[2] + '</b></li>'; 
     } else { 
      str = '<li class="on"><b class="cityname">' + match[1] + '</b><b class="cityspell">' + match[2] + '</b></li>'; 
     } 
     searchresult.push(str); 
    } 
   } 
   this.isempty = false; 
   // 如果搜索数据为空 
   if (searchresult.length == 0) { 
    this.isempty = true; 
    str = '<li class="empty">对不起,没有找到数据 "<em>' + value + '</em>"</li>'; 
    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<len;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<len;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); 
   }) 
  } 
 } 
}; 

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。