JSON+JS实现省市县三级联动下拉框

以前开发项目中,需求涉及到省市县的三级联动下拉框,可是网上的方法多数以XML+JS的方法,可是该方法可能会存在浏览器兼容问题,虽然有这个方面的解决方法,但我试过,效果不是很好,因而我找了一个JSON的实现方法,并进行了修改javascript

一、json数据,存放了全国省市县三级的数据。以下为部分数据html

{
	"北京市" : [{
		"北京市" : ["东城区", "西城区", "崇文区", "宣武区", "朝阳区", "丰台区", "石景山区", "海淀区", "门头沟区", "房山区", "通州区", "顺义区", "昌平区", "大兴区",
				"平谷区", "怀柔区", "密云县", "延庆县"]
	}]
}, {
	"天津市" : [{
		"天津市" : ["和平区", "河东区", "河西区", "南开区", "河北区", "红桥区", "塘沽区", "汉沽区", "大港区", "东丽区", "西青区", "津南区", "北辰区", "武清区",
				"宝坻区", "宁河县", "静海县", "蓟县"]
	}]
}
二、Area.js,关键的JS代码

function Area(selector){
    if (!Area.ALL_AREAS) {
        throw new Error('areas not init!');
    }
    
    this.selector = selector;
    $(this.selector).html('');
    
    var $province = this._getElement(Area.code.PROVINCE);
    var $city = this._getElement(Area.code.CITY);
    var $county = this._getElement(Area.code.COUNTY);
    
    var self = this;
    $province.change(function(){
        var province = this.value;
        $city.html(self._getOptions([province]));
        var city = $city.val();
        $county.html(self._getOptions([province, city]));
    });
    $city.change(function(){
        var province = $province.val();
        var city = this.value;
        $county.html(self._getOptions([province, city]));
    });
    $province.html(self._getOptions());
    this.select();
}

$.extend(Area, {
    ALL_AREAS: null,
    code: {
        PROVINCE: 0,
        CITY: 1,
        COUNTY: 2
    },
    init: function(url){
        if (Area.ALL_AREAS) 
            return;
        Area.ALL_AREAS = $.parseJSON($.ajax({
            url: url,
            async: false
        }).responseText);
    }
});

Area.prototype = {

    _getElement: function(code){
        return $(this.selector).find('select').eq(code);
    },
    
    select: function(address){
        var address = address || [];
        
        var $province = this._getElement(Area.code.PROVINCE);
        var $city = this._getElement(Area.code.CITY);
        var $county = this._getElement(Area.code.COUNTY);
        
        var province = address.length < 1 ? '' : address[0];
        $province.val(province);
        $city.html(this._getOptions([province]));
        
        var city = address.length < 2 ? '' : address[1];
        $city.val(city);
        $county.html(this._getOptions([province, city]));
        
        var county = address.length < 3 ? '' : address[2];
        $county.val(county);
    },
    
    getAddress: function(){
        var $province = this._getElement(Area.code.PROVINCE);
        var $city = this._getElement(Area.code.CITY);
        var $county = this._getElement(Area.code.COUNTY);
        return [$province.val(), $city.val(), $county.val()];
    },
    
    _getAreaName: function(area){
        if (typeof(area) == 'string') 
            return area;
        for (var o in area) {
            return o;
        }
    },
    
    _getAreas: function(areaName, superAreas){
        for (var i = 0; i < superAreas.length; i++) {
            if (this._getAreaName(superAreas[i]) == areaName) 
                return superAreas[i][areaName] || [];
        }
        return [];
    },
    
    _getAreasByAddress: function(address){
        var areas = Area.ALL_AREAS;
        for (var i = 0; i < address.length; i++) {
            areas = this._getAreas(address[i], areas);
        }
        return areas;
    },
    
    _getAreaNames: function(address){
        var areas = this._getAreasByAddress(address);
        var areaNames = [];
        for (var i = 0; i < areas.length; i++) {
            areaNames.push(this._getAreaName(areas[i]));
        }
        return areaNames;
    },
    
    _getOption: function(optionName){
        return '' + optionName + '';
    },
    
    _getOptions: function(address){
        var address = address || [];
        var areaNames = this._getAreaNames(address);
        var options = '请选择';
        for (var i = 0; i < areaNames.length; i++) {
            options += this._getOption(areaNames[i]);
        }
        return options;
    }
};
三、页面代码(JSP、HTML)

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>三级地市联动菜单</title>
<meta charset="UTF-8">
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<script src="${pageContext.request.contextPath}/js/jquery-1.8.3.min.js"></script>
<script src="${pageContext.request.contextPath}/js/Area.js"></script>

<script type="text/javascript">
	$(document).ready(function() {
		Area.init('area.json');
		var area = new Area('#areaContainer');
		area.select([ '请选择', '请选择' ]);

		$('#getValueBtn').click(function() {
			alert(area.getAddress());
		});
	});
</script>
<style>
body {
	font-size: 14px;
	font-family: simsun;
	margin: 0;
}
</style>
</head>

<body>
	<span id="areaContainer"></span>
	<input id="getValueBtn" type="button" value="getValue">
</body>
</html>