需求 : 热门城市、列表中的城市都需要在数据库中查询出来后构建列表,并按a-z排列,输入字母可以实现查询。

多城市选择器实现效果图

多城市选择器实现代码-LMLPHP实现:

1 后台根据登录用户获取列表中城市和热门城市的数据

@RequestMapping(value = "/getCity.do")
 2     public void getCity(PrintWriter printWriter, HttpServletResponse response)
 3     {
 4         response.setContentType("text/html;charset=UTF-8");
 5         User user = this.getLoginUser();
 6         //查询出系统登陆人所有的所属区域名称
 7       String allCity = getAllCityProperty(user.getId(), "areaName");
 8       String hotCity = getHotCity(allCity);
 9       JSONObject json = new JSONObject();        
10         json.accumulate("hotCity",hotCity);
11         json.accumulate("allCity",allCity);
12         printWriter.print(json.toString());
13         printWriter.flush();
14         printWriter.close();
15     }
登录后复制

2 前台打开界面的时候通过ajax获取城市和热门城市

 1 window.onload=function(){    
 2        var url = "/xxx/getCity.do";
 3          var params = {};
 4          $.getJSON(url,params,function(data){
 5              if(data.length==0)
 6              {
 7                   $.messager.alert('提示',"未找到数据");
 8              }else{
 9                   var hotString = data.hotCity;
10                   var allString = data.allCity;
11                 new Vcity.CitySelector({input:'city'},allString,hotString);
12                 }               
13         });
14 }
登录后复制

3 citys.js 根据百度上的城市选择组件 新增热门城市和城市变量

/* *
 * ---------------------------------------- *
 * 城市选择组件 v1.0
 * Author: zcx
 * ---------------------------------------- *
 * Date: 2016-05-17
 * ---------------------------------------- *
 * */
/* *
 * 全局空间 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,'');
    }
};
/* 正则表达式 筛选中文城市名、拼音、首字母 */
Vcity.regEx = /^([\u4E00-\u9FA5\uf900-\ufa2d]+)\|(\w+)\|(\w)\w*\|(\d+)$/i;
Vcity.regExChiese = /([\u4E00-\u9FA5\uf900-\ufa2d]+)/;
function adapterCity (citylist,hotStr) {
    if(!citylist){
        return;
    }
    var citys = citylist;
    var match;
    var letter;
    var regEx = Vcity.regEx,
        reg2 = /^[a]$/i, reg3 = /^[b]$/i, reg4 = /^[c]$/i;
        reg5 = /^[d]$/i, reg6 = /^[e]$/i, reg7 = /^[f]$/i;
        reg8 = /^[g]$/i, reg9 = /^[h]$/i, reg10 = /^[i]$/i;
        reg11 = /^[j]$/i, reg12 = /^[k]$/i, reg13 = /^[l]$/i;
        reg14 = /^[m]$/i, reg15 = /^[n]$/i, reg16 = /^[o]$/i;
        reg17 = /^[p]$/i, reg18 = /^[q]$/i, reg19 = /^[r]$/i;
        reg20 = /^[s]$/i, reg21 = /^[t]$/i, reg22 = /^[u]$/i;
        reg23 = /^[v]$/i, reg24 = /^[w]$/i, reg25 = /^[x]$/i;
        reg26 = /^[y]$/i, reg27 = /^[z]$/i;
    //if (!Vcity.oCity) {
        Vcity.oCity = {hot:{},A:{},B:{},C:{},D:{},E:{},F:{},G:{},H:{}, I:{},J:{},K:{},L:{},M:{},N:{},O:{},P:{}, Q:{},R:{},S:{},T:{},U:{},V:{},W:{},X:{},Y:{},Z:{}};
        //console.log(citys.length);
        for (var i = 0; i < citys.length; i++) {
            match = regEx.exec(citys[i]);
            letter = match[3].toUpperCase();
            if (reg2.test(letter)) {
                if (!Vcity.oCity.A[letter]) Vcity.oCity.A[letter] = [];
                Vcity.oCity.A[letter].push(match[1]);
            } else if (reg3.test(letter)) {
                if (!Vcity.oCity.B[letter]) Vcity.oCity.B[letter] = [];
                Vcity.oCity.B[letter].push(match[1]);
            } else if (reg4.test(letter)) {
                if (!Vcity.oCity.C[letter]) Vcity.oCity.C[letter] = [];
                Vcity.oCity.C[letter].push(match[1]);
            }else if (reg5.test(letter)) {
                if (!Vcity.oCity.D[letter]) Vcity.oCity.D[letter] = [];
                Vcity.oCity.D[letter].push(match[1]);
            }else if (reg6.test(letter)) {
                if (!Vcity.oCity.E[letter]) Vcity.oCity.E[letter] = [];
                Vcity.oCity.E[letter].push(match[1]);
            }else if (reg7.test(letter)) {
                if (!Vcity.oCity.F[letter]) Vcity.oCity.F[letter] = [];
                Vcity.oCity.F[letter].push(match[1]);
            }else if (reg8.test(letter)) {
                if (!Vcity.oCity.G[letter]) Vcity.oCity.G[letter] = [];
                Vcity.oCity.G[letter].push(match[1]);
            }else if (reg9.test(letter)) {
                if (!Vcity.oCity.H[letter]) Vcity.oCity.H[letter] = [];
                Vcity.oCity.H[letter].push(match[1]);
            }else if (reg10.test(letter)) {
                if (!Vcity.oCity.I[letter]) Vcity.oCity.I[letter] = [];
                Vcity.oCity.I[letter].push(match[1]);
            }else if (reg11.test(letter)) {
                if (!Vcity.oCity.J[letter]) Vcity.oCity.J[letter] = [];
                Vcity.oCity.J[letter].push(match[1]);
            }else if (reg12.test(letter)) {
                if (!Vcity.oCity.K[letter]) Vcity.oCity.K[letter] = [];
                Vcity.oCity.K[letter].push(match[1]);
            }else if (reg13.test(letter)) {
                if (!Vcity.oCity.L[letter]) Vcity.oCity.L[letter] = [];
                Vcity.oCity.L[letter].push(match[1]);
            }else if (reg14.test(letter)) {
                if (!Vcity.oCity.M[letter]) Vcity.oCity.M[letter] = [];
                Vcity.oCity.M[letter].push(match[1]);
            }else if (reg15.test(letter)) {
                if (!Vcity.oCity.N[letter]) Vcity.oCity.N[letter] = [];
                Vcity.oCity.N[letter].push(match[1]);
            }else if (reg16.test(letter)) {
                if (!Vcity.oCity.O[letter]) Vcity.oCity.O[letter] = [];
                Vcity.oCity.O[letter].push(match[1]);
            }else if (reg17.test(letter)) {
                if (!Vcity.oCity.P[letter]) Vcity.oCity.P[letter] = [];
                Vcity.oCity.P[letter].push(match[1]);
            }else if (reg18.test(letter)) {
                if (!Vcity.oCity.Q[letter]) Vcity.oCity.Q[letter] = [];
                Vcity.oCity.Q[letter].push(match[1]);
            }else if (reg19.test(letter)) {
                if (!Vcity.oCity.R[letter]) Vcity.oCity.R[letter] = [];
                Vcity.oCity.R[letter].push(match[1]);
            }else if (reg20.test(letter)) {
                if (!Vcity.oCity.S[letter]) Vcity.oCity.S[letter] = [];
                Vcity.oCity.S[letter].push(match[1]);
            }else if (reg21.test(letter)) {
                if (!Vcity.oCity.T[letter]) Vcity.oCity.T[letter] = [];
                Vcity.oCity.T[letter].push(match[1]);
            }else if (reg22.test(letter)) {
                if (!Vcity.oCity.U[letter]) Vcity.oCity.U[letter] = [];
                Vcity.oCity.U[letter].push(match[1]);
            }else if (reg23.test(letter)) {
                if (!Vcity.oCity.V[letter]) Vcity.oCity.V[letter] = [];
                Vcity.oCity.V[letter].push(match[1]);
            }else if (reg24.test(letter)) {
                if (!Vcity.oCity.W[letter]) Vcity.oCity.W[letter] = [];
                Vcity.oCity.W[letter].push(match[1]);
            }else if (reg25.test(letter)) {
                if (!Vcity.oCity.X[letter]) Vcity.oCity.X[letter] = [];
                Vcity.oCity.X[letter].push(match[1]);
            }else if (reg26.test(letter)) {
                if (!Vcity.oCity.Y[letter]) Vcity.oCity.Y[letter] = [];
                Vcity.oCity.Y[letter].push(match[1]);
            }else if (reg27.test(letter)) {
                if (!Vcity.oCity.Z[letter]) Vcity.oCity.Z[letter] = [];
                Vcity.oCity.Z[letter].push(match[1]);
            }
            /* 热门城市 */
                if(!Vcity.oCity.hot['hot']) Vcity.oCity.hot['hot'] = hotStr;
            
        }
    //}
};
/* 城市HTML模板 */
/* 城市HTML模板 */
Vcity._template = [
    '<p class="tip">热门城市(支持汉字/拼音)</p>',
    '<ul>',
    '<li class="on">热门城市</li>',
    '<li>A</li>',
    '<li>B</li>',
    '<li>C</li>',
    '<li>D</li>',
    '<li>E</li>',
    '<li>F</li>',
    '<li>G</li>',
    '<li>H</li>',
    '<li>I</li>',
    '<li>J</li>',
    '<li>K</li>',
    '<li>L</li>',
    '<li>M</li>',
    '<li>N</li>',
    '<li>O</li>',
    '<li>P</li>',
    '<li>Q</li>',
    '<li>R</li>',
    '<li>S</li>',
    '<li>T</li>',
    '<li>U</li>',
    '<li>V</li>',
    '<li>W</li>',
    '<li>x</li>',
    '<li>y</li>',
    '<li>Z</li>',
    '</ul>'
];
/* 城市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,istr,hotStr) {
        var input = options.input;
        this.input = Vcity._m.$('#'+ input);
        
        this.inputEvent(istr,hotStr);
        
    },
    /* *
     * @createWarp
     * 创建城市BOX HTML 框架
     * */
    createWarp:function(cwstr,hotStr){
        var inputPos = Vcity._m.getPos(this.input);
        var p = this.rootDiv = document.createElement('p');
        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);
        });
        p.className = 'citySelector';
        p.style.position = 'absolute';
        p.style.left = inputPos.left + 'px';
        p.style.top = inputPos.bottom + 'px';
        p.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 childp = this.cityBox = document.createElement('p');
        childp.className = 'cityBox';
        childp.id = 'cityBox';
        childp.innerHTML = Vcity._template.join('');
        var hotCity = this.hotCity =  document.createElement('p');
        hotCity.className = 'hotCity';
        childp.appendChild(hotCity);
        p.appendChild(childp);
        this.createHotCity(cwstr,hotStr);
    },
    /* *
     * @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(chstr,hotStr){
          adapterCity (chstr,hotStr);
        var op,odl,odt,odd,odda=[],str,key,ckey,sortKey,regEx = Vcity.regEx,
            oCity = Vcity.oCity;
        for(key in oCity){
            op = this[key] = document.createElement('p');
            // 先设置全部隐藏hide
            op.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'?'&nbsp;':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);
                op.appendChild(odl);
            }
            // 移除热门城市的隐藏CSS
            Vcity._m.removeClass('hide',this.hot);
            this.hotCity.appendChild(op);
        }
        document.body.appendChild(this.rootDiv);
        /* IE6 */
        this.changeIframe();
        this.tabChange();
        this.linkEvent();
    },
    /* *
     *  tab按字母顺序切换
     *  @ tabChange
     * */
    tabChange:function(){
        var lis = Vcity._m.$('li',this.cityBox);
        var ps = Vcity._m.$('p',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',ps[j]);
                }
                Vcity._m.addClass('on',this);
                Vcity._m.removeClass('hide',ps[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(iestr,hotStr){
        var that = this;
        Vcity._m.on(this.input,'click',function(event){
            event = event || window.event;
            if(!that.cityBox){
                that.createWarp(iestr,hotStr);
            }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(iestr);
            /* 移除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 (iestr) {
        if(!iestr){
            return;
        }
        //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 = [];
            /* *
             *【修改5】
             * 这里原本是遍历Vcity.allCity,现在改用citylist
             * zcx 2016-5-17
             */
            
            for (var i = 0; i < iestr.length; i++) {
                if (reg.test(iestr[i])) {
                    var match = Vcity.regEx.exec(iestr[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);
            })
        }
    }
}
登录后复制

更多多城市选择器实现代码请关注Work网(www.php.cn)其它文章!


08-28 07:27