Ajax实现省市区 三级联动
浅谈Ajax
Ajax(Asynchronous JavaScript and XML)异步的javaScript和xml,即可以在整个页面不刷新的情况下,实现局部页面的刷新,主要要的例子有:新浪微博,当然也可以实现三级联动的效果,这正是本博客要着重介绍的内容。
原理图解:
效果图:
实现步骤:
- 编写三级联动页面
请选择地址:
<select id="province" name="province">
</select>
<select id="city" name="city">
</select>
<select id="area" name="area">
</select>
2.为body添加onload事件,使得在页面加载的同时就获得省份的值,并且赋值给省份的下拉选择框
<body onload="getProvince()">
3.Ajax编写getProvince()得到省份信息
<script type="text/javascript"> //封装生成xmlHttp对象 var xmlHttp; function getXMLHttpRequest() { if (window.XMLHttpRequest) { return new XMLHttpRequest(); } else { return new ActiveXObject("Microsoft.XMLHTTP"); } } //Ajax得到省份 function getProvince() { //1.生成xmlHttp对象 xmlHttp = getXMLHttpRequest(); //2.设置请求参数(method,url,async) xmlHttp.open("Get", "../../GetProvinceServlet", true); //3.监听服务器返回的数据 xmlHttp.onreadystatechange = getProvinceCallBack; //4.发送请求 xmlHttp.send(); } //3.获得省份的回调函数 function getProvinceCallBack() { if (xmlHttp.readyState == 4 && xmlHttp.status == 200) { //接收服务器返回的数据 var xmlDoc = xmlHttp.responseXML; var provinces = xmlDoc.getElementsByTagName("province"); var provinceSelect = document.getElementById("province"); for (var i = 0; i < provinces.length; i++) { var option = document.createElement("option"); option.value = provinces[i].firstChild.firstChild.nodeValue; option.text = provinces[i].lastChild.firstChild.nodeValue; provinceSelect.appendChild(option); } getCity(provinceSelect.value); } }
4.编写GetProvinceServlet从数据库得到省份信息
package cn.com.mp.front.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.com.mp.front.service.LinkageService;
import cn.com.mp.utils.DbUtil;
@WebServlet("/GetProvinceServlet")
public class GetProvinceServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public GetProvinceServlet() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//得到省份数据
LinkageService service = new LinkageService();
List<Map<String, Object>> list=service.getProvince();
//以xml的形式将获得的数据缓存到response中
response.setContentType("text/xml;charset=utf-8");
PrintWriter out=response.getWriter();
out.write("<root>");
for(Map<String ,Object> map:list){
out.write("<province>");
out.write("<id>");
out.write(map.get("provinceid").toString());
out.write("</id>");
out.write("<name>");
out.write(map.get("province").toString());
out.write("</name>");
out.write("</province>");
}
out.write("</root>");
out.flush();
out.close();
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
5.为省份下拉选择框添加onchange事件,在省份下拉框中的值发生变化的同时,得到对应市区的信息,实现联动
<select id="province" name="province" onchange="getCity(this.value)">
6.以同样的方式,使用Ajax实现getCity()
//Ajax得到市
function getCity(proCode) {
//1.
xmlHttp = getXMLHttpRequest();
//2.
xmlHttp.open("Get", "../../GetCityServlet?code=" + proCode, true);
//3.
xmlHttp.onreadystatechange = getCityCallBack;
//4.
xmlHttp.send();
}
//3.获得市的回调函数
function getCityCallBack() {
if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
var xmlDoc = xmlHttp.responseXML;
var cities = xmlDoc.getElementsByTagName("city");
var citySelect = document.getElementById("city");
citySelect.length = 0;
for (var i = 0; i < cities.length; i++) {
var option = document.createElement("option");
option.value = cities[i].firstChild.firstChild.nodeValue;
option.text = cities[i].lastChild.firstChild.nodeValue;
citySelect.appendChild(option);
}
getArea(citySelect.value);
}
}
-------------------
getCityServlet:
package cn.com.mp.front.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.com.mp.front.service.LinkageService;
import cn.com.mp.utils.DbUtil;
@WebServlet("/GetCityServlet")
public class GetCityServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public GetCityServlet() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 得到对应市的数据
String proCode = request.getParameter("code");
LinkageService service = new LinkageService();
List<Map<String, Object>> list = service.getCity(proCode);
// 以xml的形式缓存到response中
response.setContentType("text/xml;charset=UTF-8");
PrintWriter out = response.getWriter();
out.write("<root>");
for (Map<String, Object> map : list) {
out.write("<city>");
out.write("<id>" + map.get("cityid") + "</id>");
out.write("<name>" + map.get("city") + "</name>");
out.write("</city>");
}
out.write("</root>");
out.flush();
out.close();
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
7.同理得到区的信息
<select id="city" name="city" onchange="getArea(this.value)">
</select>
//Ajax得到区
function getArea(cityCode) {
//1.
xmlHttp = getXMLHttpRequest();
//2.
xmlHttp.open("Get", "../../GetAreaServlet?code=" + cityCode, true);
//3.
xmlHttp.onreadystatechange = getAreaCallBack;
//4.
xmlHttp.send();
}
//3.得到区的回调函数
function getAreaCallBack() {
if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
var xmlDoc = xmlHttp.responseXML;
var areas = xmlDoc.getElementsByTagName("area");
var areaSelect = document.getElementById("area");
areaSelect.length = 0;
for (var i = 0; i < areas.length; i++) {
var option = document.createElement("option");
option.value = areas[i].firstChild.firstChild.nodeValue;
option.text = areas[i].lastChild.firstChild.nodeValue;
areaSelect.appendChild(option);
}
}
}
getAreaServlet
--------------
package cn.com.mp.front.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.com.mp.front.service.LinkageService;
import cn.com.mp.utils.DbUtil;
@WebServlet("/GetAreaServlet")
public class GetAreaServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public GetAreaServlet() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 得到对应的区
String cityCode = request.getParameter("code");
LinkageService service = new LinkageService();
List<Map<String, Object>> list = service.getArea(cityCode);
// 以xml的形式缓存得到区的数据
response.setContentType("text/xml;charset=UTF-8");
PrintWriter out = response.getWriter();
out.write("<root>");
for (Map<String, Object> map : list) {
out.write("<area>");
out.write("<id>" + map.get("areaid") + "</id>");
out.write("<name>" + map.get("area") + "</name>");
out.write("</area>");
}
out.write("</root>");
out.flush();
out.close();
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
8.总结
Ajax可以在不刷新整个页面的情况下,实现与服务器的数据交换,这样使得整个网页更加流畅,不仅仅可以使用Ajax实现三级联动,还可以实现比如说:密码确认,用户名是否重复等等一些列功能,本博客这是学习的记录,仅仅是冰山一角,有错误的地方还请大家指教。