代码改变世界

JS省市区联动效果

2014-02-23 17:30 龙恩0707 阅读(...) 评论(...) 编辑 收藏

     省市区联动下拉效果在WEB中应用非常广泛,尤其在电商网站最为常见。一般使用Ajax实现无刷新下拉联动。利用jQuery,通过读取JSON数据,实现无刷新动态下拉省市二(三)级联动效果。

  首先我们可以看看自定义参数配置项如下:

  参数配置如下:

  url 'js/city.min.js',   省市区JSON数据
 provId  '#prov',         默认省份ID
cityId  '#city'                   默认城市ID
 areaId   '#area'                默认区ID
 prov  null ,                        参数是否传入默认的省份
 city  null,                        参数是否传入默认的市
 area  null ,                        参数是否传入默认的区
 required  true,                        必填项 默认为true

接下来HTML代码如下:

<div id="city_4">
      <select class="prov" id="prov4"></select> 
        <select class="city" disabled="disabled" id="city4"></select>
        <select class="dist" disabled="disabled" id="area4"></select>
</div>

如果没有三级联动的话 那么区的HTML代码可以省略掉!

调用非常简单如下:

new CitySelect({
    provId : "#prov4",
    cityId : '#city4',
    areaId : '#area4',
    prov:"湖南", 
        city:"长沙"
});

废话也不多说,贴代码如下:

HTML代码:

<div id="main">
  <div class="demo">
      <h3>直接调用</h3>
    <p>二级联动,默认选项为:请选择</p>
      <div id="city_1">
          <select class="prov" id="prov1"></select> 
        <select class="city" disabled="disabled" id="city1"></select>
    </div>
    <p>三级联动,默认省份:北京,隐藏无数据的子级select</p>
    <div id="city_2">
          <select class="prov" id="prov2"></select> 
        <select class="city" disabled="disabled" id="city2"></select>
        <select class="dist" disabled="disabled" id="area2"></select>
    </div>
  </div>
  
  <div class="demo">
      <h3>设置省份、城市、地区(县)的默认值</h3>
    <p>二级联动</p>
      <div id="city_3">
          <select class="prov" id="prov3"></select> 
        <select class="city" disabled="disabled" id="city3"></select>
    </div>
    <p>三级联动</p>
    <div id="city_4">
          <select class="prov" id="prov4"></select> 
        <select class="city" disabled="disabled" id="city4"></select>
        <select class="dist" disabled="disabled" id="area4"></select>
    </div>
  </div>
  
  <div class="demo">
      <h3>自定义下拉选项</h3>
      <div id="city_5">
          <select class="prov" id="prov5"></select>
        <select class="city" disabled="disabled" id="city5"></select>
        <select class="dist" disabled="disabled" id="area5"></select>
    </div>
  </div>
</div>

JS代码如下:

/**
 * JS省市区联动
 * @constructor CitySelect
 * @author tugenhua
 * @time 2014-2-22
 * @email 879083421@qq.com
 */

 function CitySelect(options) {
    
    this.config = {
        url       :   "js/city.min.js",
        provId    :   '#prov',
        cityId    :   '#city',
        areaId    :   '#area',
        prov      :   null,
        city      :   null,
        area      :   null,
        required  :   true
    };

    this.cache = {
        select_prehtml  : '',          // 下拉框默认选项
        city_json       : ''           //  城市json                
    };

    this.init(options);
 }
 
 CitySelect.prototype = {

    constructor : CitySelect,
    
    init: function(options) {
        this.config = $.extend(this.config, options || {});
        var self = this,
            _config = self.config,
            _cache = self.cache;
        
        _cache.select_prehtml = _config.required ? '' : "<option value=''>请选择</option>";

        // 设置省市的数据
        if(typeof(_config.url) == 'string') {
            $.getJSON(_config.url, function(json) {
                _cache.city_json = json;
                self._provFunc();
            });
        }else {
            _cache.city_json = _config.url;
            self._provFunc();
        }
    },
    /*
     * 渲染省份函数
     * @method _provFunc
     */
    _provFunc: function() {
        var self = this,
            _config = self.config,
            _cache = self.cache;
        
        var html = _cache.select_prehtml;

        // 遍历 获取省份
        $(_cache.city_json.citylist).each(function(i,prov){
            html += "<option value='"+prov.p+"'>"+prov.p+"</option>";
        });
        $(_config.provId).html(html);

        /*
         * 若有传入省份与市级的值,则选中。(setTimeout为兼容IE6而设置)
         * 发现取到的selectedIndex老是前面一次
         */
        t && clearTimeout(t);
        var t = setTimeout(function(){
            if(_config.prov != null) {
                $(_config.provId).val(_config.prov);
                self._cityStart();
                setTimeout(function(){
                    if(_config.city != null) {
                        $(_config.cityId).val(_config.city);
                        self._areaStart();
                        setTimeout(function(){
                            if(_config.area != null) {
                                $(_config.areaId).val(_config.area);
                            }
                        },1);
                    }
                },1);
            }
        },1);

        // 选择省份时发生事件
        $(_config.provId).unbind('change').bind('change',function(){
            self._cityStart();
        });
        // 选择市级时发生事件
        $(_config.cityId).unbind('change').bind('change',function(){
            self._areaStart();
        });
    },
    /*
     * 渲染市函数
     * @method _cityStart
     */
    _cityStart: function() {
        var self = this,
            _config = self.config,
            _cache = self.cache;
        var prov_id = $(_config.provId).get(0).selectedIndex;
        if(!_config.required){
            prov_id--;
        };
        $(_config.cityId).empty().attr("disabled",true);
        $(_config.areaId).empty().attr("disabled",true);

        if(prov_id < 0 || typeof(_cache.city_json.citylist[prov_id].c)=="undefined"){

            return;
        }
        
        var html = _cache.select_prehtml;

        $.each(_cache.city_json.citylist[prov_id].c,function(i,city){
            html += "<option value='"+city.n+"'>"+city.n+"</option>";
        });
        
        $(_config.cityId).html(html).attr('disabled',false);
        
        self._areaStart();
    },
    /*
     * 渲染区函数
     * @method _areaStart
     */
    _areaStart: function(){
        var self = this,
            _config = self.config,
            _cache = self.cache;
        var prov_id=$(_config.provId).get(0).selectedIndex,
            city_id=$(_config.cityId).get(0).selectedIndex;
        if(!_config.required){
            prov_id--;
            city_id--;
        };
        $(_config.areaId).empty().attr("disabled",true);

        if(prov_id<0||city_id<0||typeof(_cache.city_json.citylist[prov_id].c[city_id].a)=="undefined"){
            return;
        };
        var html = _cache.select_prehtml;

        $.each(_cache.city_json.citylist[prov_id].c[city_id].a,function(i,area){
            html += "<option value='"+area.s+"'>"+area.s+"</option>";
        });
        
        $(_config.areaId).html(html).attr('disabled',false);
        
        
    }
 };

调用如下:

$(function(){
    new CitySelect({
        prov:'北京',
        provId : "#prov1",
        cityId : '#city1'
    });
    
    new CitySelect({
        provId : "#prov2",
        cityId : '#city2',
        areaId : '#area2'
    });
    new CitySelect({
        provId : "#prov3",
        cityId : '#city3'
    });
    new CitySelect({
        provId : "#prov4",
        cityId : '#city4',
        areaId : '#area4',
        prov:"湖南", 
        city:"长沙"
    });
    new CitySelect({
        provId : "#prov5",
        cityId : '#city5',
        areaId : '#area5'
    });
});

DEMO下载