JS省市區聯動效果

龍恩0707發表於2014-02-23

     省市區聯動下拉效果在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下載

相關文章