<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <title>多级联动菜单</title> <mce:script type="text/javascript"><!-- var xmlHttp; //用于保存XMLHttpRequest对象的全局变量 var targetSelId; //用于保存要更新选项的列表id var selArray; //用于保存级联菜单id的数组 //用于创建XMLHttpRequest对象 function createXmlHttp() { //根据window.XMLHttpRequest对象是否存在使用不同的创建方式 if (window.XMLHttpRequest) { xmlHttp = new XMLHttpRequest(); //FireFox、Opera等浏览器支持的创建方式 } else { xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");//IE浏览器支持的创建方式 } } //获取列表选项的调用函数 function buildSelect(selectedId, targetId) { if (selectedId == "") { //selectedId为空串表示选中了默认项 clearSubSel(targetId); //清除目标列表及下级列表中的选项 return; //直接结束函数调用,不必向服务器请求信息 } targetSelId = targetId; //将传入的目标列表id赋值给targetSelId变量 createXmlHttp(); //创建XmlHttpRequest对象 xmlHttp.onreadystatechange = buildSelectCallBack; //设置回调函数 xmlHttp.open("GET", "getMenu.jsp?selectedId=" + selectedId, true); xmlHttp.send(null); } //获取列表选项的回调函数 function buildSelectCallBack() { if (xmlHttp.readyState == 4) { var optionsInfo = eval("("+xmlHttp.responseText+")"); //将从服务器获得的文本转为对象直接量 var targetSelNode = document.getElementById(targetSelId); clearSubSel(targetSelId); //清除目标列表中的选项 //遍历对象直接量中的成员 for (var o in optionsInfo) { targetSelNode.appendChild(createOption(o, optionsInfo[o])); //在目标列表追加新的选项 } } } //根据传入的value和text创建选项 function createOption(value, text) { var opt = document.createElement("option"); //创建一个option节点 opt.setAttribute("value", value); //设置value opt.appendChild(document.createTextNode(text)); //给节点加入文本信息 return opt; } //清除传入的列表节点内所有选项 function clearOptions(selNode) { selNode.length = 1; //设置列表长度为1,仅保留默认选项 selNode.options[0].selected = true; //选中默认选项 } //初始化列表数组(按等级) function initSelArray() { selArray = arguments; //arguments对象包含了传入的所有参数 } //清除下级子列表选项 function clearSubSel(targetId) { var canClear = false; //设置清除开关,初始值为假 for (var i=0; i<selArray.length; i++) { //遍历列表数组 if (selArray[i]==targetId) { //当遍历至目标列表时,打开清除开关 canClear = true; } if (canClear) { //从目标列表开始到最下级列表结束,开关始终保持打开 clearOptions(document.getElementById(selArray[i])); //清除该级列表选项 } } } // --></mce:script> </head> <!-- 页面加载完毕做两件事:1.初始化列表数组 2.为第一个列表赋值 --> <body οnlοad="initSelArray('selA','selB','selC');buildSelect('0', 'selA')"> <h1>多级联动菜单</h1> <form> <select name="selA" id="selA" οnchange="buildSelect(this.value, 'selB')"> <option value="" selected>----请选择----</option> </select> <select name="selB" id="selB" οnchange="buildSelect(this.value, 'selC')"> <option value="" selected>----请选择----</option> </select> <select name="selC" id="selC"> <option value="" selected>----请选择----</option> </select> </form> </body> </html> jsp code <%@ page contentType="text/plain; charset=UTF-8"%> <%@ page language="java"%> <%@ page import="java.sql.*,com.ldc.shopping.util.*"%> <%! //访问数据库取得下级选项信息 String getOptions(String selectedId) { int counter = 0; //计数器 StringBuffer opts = new StringBuffer("{"); //保存选项信息 String sql = "select * from category where pid = ? order by cno asc";//定义查询数据库的SQL语句 Connection conn = null; //声明Connection对象 PreparedStatement pstmt = null; //声明PreparedStatement对象 ResultSet rs = null; //声明ResultSet对象 try { conn = DB.getConn(); //获取数据库连接 pstmt = conn.prepareStatement(sql); //根据sql创建PreparedStatement pstmt.setString(1, selectedId); //设置参数 rs = pstmt.executeQuery(); //执行查询,返回结果集 while (rs.next()) { //遍历结果集 //如果不是第一项,追加一个“,”用于分隔选项 if (counter > 0) { opts.append(","); } opts.append("'"); opts.append(rs.getString("id")); opts.append("':'"); if(selectedId.equals("0")){ opts.append(rs.getString("name")+"-->"); }else{ opts.append(rs.getString("name")); } opts.append("'"); counter++; //计数器加1 } } catch (SQLException e) { System.out.println(e.toString()); } finally { DB.close(rs); //关闭结果集 DB.close(pstmt); //关闭PreparedStatement DB.close(conn); //关闭连接 } opts.append("}"); return opts.toString(); } %> <% out.clear(); //清空当前的输出内容(空格和换行符) String selectedId = request.getParameter("selectedId"); //获取selectedId参数 String optionsInfo = getOptions(selectedId); //调用getOptions方法取得下级选项信息 out.print(optionsInfo); //输出下级选项信息 %> 表结构 |----id----pid----name---| |_____|____|_______| |_____|____|_______|