使用ajax实现二级联动

思路

  1. 在加载页面的时候,后台读取xml文件中的所有省份信息,显示到下拉框中
    a) 页面加载ajax发送异步请求到servlet
    b) servlet解析china.xml然后获取所有的省份的名称
    c) Servlet向jsp响应省份信息
    d) 通过jquery将每一个省份的名字添加到select下

因为在服务端需要进行xml文件的解析, 所以需要导入相应的jar包.
image.png

2.点击省份下拉框的时候触发内容改变

1.获取当前选中的省份信息
2.通过ajax请求serlvet 并且将当前的省份名称传递过去
3.Servlet根据省份名称去解析china.xml文件,获取该省份的xml片段
4.将xml片段相应给jsp
5.解析xml片段 将对应的城市信息添加到select下
image.png

首先, 将保存有中国省市信息的xml文件放到类路径下, china.xml:

<?xml version="1.0" encoding="utf-8"?>
<china>
    <province name="北京">
        <city>东城区</city>
        <city>西城区</city>
        <city>崇文区</city>
        <city>宣武区</city>
        <city>朝阳区</city>
        <city>丰台区</city>
        <city>石景山区</city>
        <city>海淀区</city>
        <city>门头沟区</city>
        <city>房山区</city>
        <city>通州区</city>
        <city>顺义区</city>
        <city>昌平区</city>
        <city>大兴区</city>
        <city>怀柔区</city>
        <city>平谷区</city>
        <city>密云县</city>
        <city>延庆县</city>
    </province>
    <province name="天津">
        <city>和平区</city>
        <city>河东区</city>
        <city>河西区</city>
        <city>南开区</city>
        <city>河北区</city>
        <city>红桥区</city>
        <city>塘沽区</city>
        <city>汉沽区</city>
        <city>大港区</city>
        <city>东丽区</city>
        <city>西青区</city>
        <city>津南区</city>
        <city>北辰区</city>
        <city>武清区</city>
        <city>宝坻区</city>
        <city>宁河县</city>
        <city>静海县</city>
        <city>蓟县</city>
    </province>
    // ...
</china>

客户端代码: province_city.jsp

<%--
  User: menglanyingfei
  Date: 2018/1/29
  Time: 10:07
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
    <title>省市联动</title>
    <script type="text/javascript" src="js/createXMLHttp.js"></script>
    <script type="text/javascript" src="js/jquery-1.4.4.js"></script>

</head>
<body>
    <select id="province">
        <option>--请选择--</option>
    </select>
    &nbsp;&nbsp;&nbsp;&nbsp;
    <select id="city">
        <option>--请选择--</option>
    </select>
</body>

<script type="text/javascript">
    // 页面加载发送请求到servlet
    $(function () {
        var xmlHttp = createXmlHttp();
//        alert(xmlHttp);

        xmlHttp.open("get",
            "${pageContext.request.contextPath}/ProvinceCityServlet", true);
        xmlHttp.send(null);
//        alert(xmlHttp);

        xmlHttp.onreadystatechange = function () {

            if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
//                alert("1");
                // 切割字符串
                var proList = xmlHttp.responseText.split("|");
//                alert(proList.length); // 34
                for (var i = 0; i < proList.length; i++) {
                    // 创建一个option jquery对象
                    var $option = $("<option>"
                        + proList[i] + "</option>");
                    // 给option设置value属性值
                    $option.val(proList[i]);
                    // 将option元素添加到select下
                    $("#province").append($option);
                }
            }
        };
    });

    // 给id为province的select 添加内容改变事件
    $("#province").change(function () {
        // 每次触发该事件的时候, 先将以前的option元素删掉, 只留下第一个
        $("#city option:gt(0)").each(function () {
            $(this).remove();
        });

       // 获取该select的value值, 也就是被选中的省份名称
       var proName = this.value;
        var xmlHttp = createXmlHttp();
        xmlHttp.open("post",
            "${pageContext.request.contextPath}/ProvinceCityServlet", true);
        // 设置请求头
        xmlHttp.setRequestHeader("content-type",
        "application/x-www-form-urlencoded");

        xmlHttp.send("proName=" + proName);
        xmlHttp.onreadystatechange = function () {

            if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
//                alert("test");
                var xmlDoc = xmlHttp.responseXML;
                // 获取所有的city子元素, 是一个集合
                var cityList = xmlDoc.getElementsByTagName("city");
                // 遍历, 得到每一个具体的city元素
//                alert(cityList.length);

                for (var i = 0; i < cityList.length; i++) {
                    // 将city子元素转换成jquery对象
                    var $city = $(cityList[i]);
                    // 获取city元素中的文本内容
                    var cityName = $city.html();
                    // 根据城市名称创建option元素
                    var $option = $("<option>" + cityName + "</option>");
                    // 设置value属性值
                    $option.val(cityName);
                    // 添加到select元素中
                    $("#city").append($option);
                }

            }
        };

    });
</script>
</html>

createXMLHttp.js: 用来创建XMLHttpRequest对象

// ajax的四个步骤
// 创建XMLHttpRequest对象
function createXmlHttp() {
    var xmlHttp;
    try {
        xmlHttp = new XMLHttpRequest();
    } catch (e) {
        try {
            xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
        } catch (e) {
            try {
                xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
            } catch (e) {
                alert("浏览器太老,不能使用ajax");
            }
        }
    }

    return xmlHttp;
}

服务端代码:

@WebServlet(name = "ProvinceCityServlet", value = "/ProvinceCityServlet")
public class ProvinceCityServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 请求编码
        request.setCharacterEncoding("utf-8");
        // 响应格式
        response.setContentType("text/xml;charset=utf-8");
        // 获取请求参数
        String proName = request.getParameter("proName");
        // 创建解析器
        SAXReader reader = new SAXReader();

        try {
            // 解析china.xml得到Document对象
            Document doc = reader.read(this.getClass().getResourceAsStream("/china.xml"));
            // 查询name为proName的province片段
            Element proEle = (Element) doc.selectSingleNode("//province[@name='" +proName +"']");
            // 将proEle转换成xml格式的字符串
            String strEle = proEle.asXML();
            // 响应
            response.getWriter().print(strEle);
        } catch (DocumentException e) {
            e.printStackTrace();
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 设置响应编码
        response.setContentType("text/html;charset=utf-8");
        // 创建解析器
        SAXReader reader = new SAXReader();
        // 得到xml文件对应的Document对象
        try {
            Document doc = reader.read(this.getClass().getResourceAsStream("/china.xml"));
            // 获取province元素的属性节点(XPath)
            List<Attribute> attrList =
                    doc.selectNodes("//province/@name");
            // 采用StringBuilder来拼接所有的省份名称
            StringBuilder sb = new StringBuilder();

            for (int i = 0; i < attrList.size(); i++) {
                // 获取每一个属性节点的属性值
                String proName = attrList.get(i).getValue();
                sb.append(proName);
                // 北京,天津...台湾
                if (i < attrList.size() - 1) {
                    sb.append("|");
                }

            }
            // 响应
            response.getWriter().print(sb.toString());

        } catch (DocumentException e) {
            e.printStackTrace();
        }


    }
}

成功运行演示:
demo.gif

完整代码地址

https://github.com/menglanyingfei/front-end-Learning/tree/master/ajax%26json/ajax-day02

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值