JQuery+DIV+CSS+Ajax实现省市区三级联动(模块化实现)

今天给项目做一个省市区三级联动的功能模块,想起以前的写过的比较粗糙的实现方式,忽然觉得,有必要把这次的实现方式记录下来,给自己留个方便,也给需要的朋友留个方便。如果看到的朋友觉得好,帮忙给个赞

------------------------------------------------------------------------------------------------------------------------------

原理很简单,打开页面时加载省份的数据,当省份发生变化时,触发事件获取对应省份的城市,并显示在省份后面,

同理,当城市发生变化时,触发事件获取对应的区县并显示在城市的后面。

考虑到以前按部就班的实现方式,这次对代码进行了优化,希冀实现模块化,以便于提升可用性、重用性,减少服务器消耗的资源(资源再少也是肉啊~)。


↓↓↓↓↓↓↓  废话不多说,开始上代码。↓


1.先布局前端DIV,需要的选择的是省份、城市、区县,当然,咱们不能弄的太难看,再附上CSS样式

<!----------------------- 省市区三级联动布局 ----------------------->
<div id="china_pca">
	<div id="china_p" class="china_p">
		<font class="china_f">省份:</font>
		<select class="china_s" id="province" name="province">
			<option>请选择省份</option>
			<c:forEach items="${provincelist }" var="province">
				<option value="${province.code }">${province.name }</option>
			</c:forEach>
		</select>
	</div>
	<div id="china_c" class="china_ca">
		<font class="china_f">城市:</font>
		<select class="china_s" id="city" name="city">
		</select>
	</div>
	<div id="china_a" class="china_ca">
		<font class="china_f">区县:</font>
		<select class="china_s" id="area" name="area">
		</select>
	</div>
</div>
/**************************** 省市区三级联动  ****************************/
#china_pca{height: 50px;width: 550px;}
.china_p{width: 150px;float:left;margin-right: 6px;}
.china_ca{width: 150px;float:left;margin-right: 6px;display: none;}
.china_f{color:#457887;font-size: 15px;width: 50px;}
.china_s{width: 100px;border-radius: 8px 8px 8px 8px;}

完成DIV和CSS后,就开始做主要的交互了,需要达到的效果的是,选择省份的时候,不能显示城市与区县;

选择城市的时候,不能显示区县。


2.用JQuery给选择标签绑定change事件,通过Ajax获取对应的城市或者区县的数据。城市和区县的数据获取

方式是一致的,秉持精良精简的原则,便有了下面的JS代码,以及对应的后端方法。

/********************************* 省市区三级联动 *********************************/
	$("#province").change(function(){
		$("#china_c").css({"display":"none"});
		$("#china_a").css({"display":"none"});
		var province=$(this).children('option:selected').val();
		showCityArea(province,'city');
	})
	$("#city").change(function(){
		$("#china_a").css({"display":"none"});
		var province=$(this).children('option:selected').val();
		showCityArea(province,'area');
	})
		
		
	function showCityArea(chinacode,chinatype){
		$.ajax({
			type :	"post",
			url	 :	host+"find/cityarea",
			data :	{code:chinacode,type:chinatype},
			dataType : 'json', 
			success : function(data,status){
				if(status=="success"){
					if(data==null){alert("出错啦,请联系技术人员");return;}
					if(chinatype=="city"){var str="<option value=\"0\">请选择城市</option>";}
					if(chinatype=="area"){var str="<option value=\"0\">请选择区县</option>";}
					for(var i=0;i<data.length;i++){
						str+="<option value=\""+data[i].code+"\">"+data[i].name+"</option>";
					}
					$("#"+chinatype+"").html(str);
					if(chinatype=="city"){$("#china_c").css({"display":"block"});}
					if(chinatype=="area"){$("#china_a").css({"display":"block"});}
					
				}
			}
		})
	}

Controller中的对应的方法:

/** 
 * @author  JQ.Wang   E-mail:wang53400487@hotmail.com 
 * @date 创建时间:2015年8月6日 下午6:18:07 
 * @version 1.0 
 * @parameter  
 * @since  JDK1.7
 * @return  
 */
@Controller
public class IndexController extends ApplicationController{
	
	protected static final Logger logger=Logger.getLogger(IndexController.class);
	
	@Autowired
	private DataMessageService dataMessageService;
	
	/**
	 * 示例:内容传递 省市区三级联动实现
	 * 方法参数使用HttpServletRequest实现内容传递
	 * 需要使用省市区三级联动的页面,在路径控制Controller中加入下面所示代码块即可
	 * @param request
	 * @return 
	 */
	@RequestMapping("/say")
	public String say(HttpServletRequest request){
		//省市区三级联动 调用
		List<ChinaProvince> provincelist=DZSession();
		
		request.setAttribute("provincelist", provincelist);
		
		return "SayHello";
	}
	
	/**
	 * 示例:ajax前后端交互  对象转换成json
	 * 通过定义路径,访问类型,对应的传入参数,
	 * 添加  ResponseBody 注解
	 * 使用HttpServletResponse实现前后端的交互
	 * @param code
	 * @param type
	 * @param response
	 * @return
	 */
	@RequestMapping(value={"/find/cityarea"},method=RequestMethod.POST)
	public @ResponseBody String getCityArea(@RequestParam("code")String code,
			@RequestParam("type")String type,HttpServletResponse response){
		response.setContentType("html/text;charset=utf-8");
		if (type.equals("city")) {
			List<ChinaCity> cityList=Cache.getCityList(code);
			return Cache.toJson(cityList);
		}
		if (type.equals("area")) {
			List<ChinaArea> areaList=Cache.getAreaList(code);
			return Cache.toJson(areaList);
		}
		return null;
	}
}
@Controller
public class ApplicationController {

	protected static final Logger logger=Logger.getLogger(IndexController.class);
	
	@Autowired
	private ChinaProvinceService chinaProvinceService;
	
	@Autowired
	private ChinaCityService chinaCityService;
	
	@Autowired
	private ChinaAreaService chinaAreaService;
	
	/**
	 * 地址区域缓存,获取省份列表
	 * 优先级从缓存中获取省市区信息
	 * 识别是否需要从数据库中获取省市区信息
	 * @return List
	 */
	public List<ChinaProvince> DZSession(){
		/*****           省市区三级联动 代码块          ************/
		List<ChinaProvince> provincelist=Cache.cpProvince;
		List<ChinaCity> citylist=Cache.cpCity;
		List<ChinaArea> arealist=Cache.cpArea;
		if (provincelist.isEmpty()) {
			provincelist=chinaProvinceService.findAll();
			Cache.cpProvince=provincelist;
		}
		if (citylist.isEmpty()) {
			citylist=chinaCityService.findAll();
			Cache.cpCity=citylist;
		}
		if (arealist.isEmpty()) {
			arealist=chinaAreaService.findAll();
			Cache.cpArea=arealist;
		}
		logger.info("=======================省:"+provincelist.size());
		logger.info("=======================市:"+citylist.size());
		logger.info("=======================区:"+arealist.size());
		return provincelist;
	}
}

还有关键的缓存设置:

public class Cache {
	
	protected static final Logger log=Logger.getLogger(Cache.class);

	//省市区信息
	public static List<ChinaProvince> cpProvince=new ArrayList<ChinaProvince>();
	public static List<ChinaCity> cpCity=new ArrayList<ChinaCity>();
	public static List<ChinaArea> cpArea=new ArrayList<ChinaArea>();
	
	//Jackson框架-转Json所需对象
	public static ObjectMapper objectMapper=new ObjectMapper();
	
	/**
	 * 获取所在省的所有市
	 * @param provinceCode
	 * @return List
	 */
	public static List<ChinaCity> getCityList(String provinceCode){
		List<ChinaCity> cc=new ArrayList<ChinaCity>();
		for (ChinaCity c : cpCity) {
			if (c.getProvincecode().equals(provinceCode)) {
				cc.add(c);
			}
		}
		return cc;
	}
	
	/**
	 * 获取所在市的所有区县
	 * @param cityCode
	 * @return List
	 */
	public static List<ChinaArea> getAreaList(String cityCode){
		List<ChinaArea> cc=new ArrayList<ChinaArea>();
		for (ChinaArea c : cpArea) {
			if (c.getCitycode().equals(cityCode)) {
				cc.add(c);
			}
		}
		return cc;
	}
	
	/**
	 * List转换Json
	 * @param param
	 * @return String
	 */
	public static String toJson(List<?> param){
		if (param==null||param.isEmpty()) {
			return null;
		}
		String jsonStr=null;
		try {
			jsonStr = objectMapper.writeValueAsString(param);
		} catch (IOException e) {
			e.printStackTrace();
		}
		log.info("==============================jsonStr:"+jsonStr);
		return jsonStr;
	}
}


完成以上这些代码后,发现如果某个页面需要选择区域,只需继承ApplicationController,

调用 DZSession()  就可以了,而且这种缓存方式比较直观,实用。


受于技术限制,若有不妥当之处,欢迎留言指正。

转载于:https://my.oschina.net/JQWang/blog/494813

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值