您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關jQuery如何實現級聯下拉框,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
效果功能如下:
頁面默認只提供汽車廠商,當選擇了具體的某品牌汽車,汽車類型下拉框就會動態的顯示出來,選擇對應的類型,然后出來該汽車類型對應的輪胎類型下拉框顯示出來,選中輪胎類型,頁面的正中間會顯示出汽車的圖片。
思路分析如圖:
建立我們的html頁面,程序清單如下:
代碼清單1.1: chainSelect.jsp
<body> <div class="loading"> <p><img src="../image/data-loading.gif" alt="數據裝載中" /></p> <p>數據裝載中......</p> </div> <div class="car"> <span class="carname"> 汽車廠商: <select> <option value="" selected="selected">請選擇汽車廠商</option> <option value="BMW">寶馬</option> <option value="Audi">奧迪</option> <option value="VW">大眾</option> </select> <img src="../image/pfeil.gif" alt="有數據"> </span> <span class="cartype"> 汽車類型: <select> <option selected="selected">默認選項</option> <option>Test1</option> </select> <img alt="有數據" src="../image/pfeil.gif"> </span> <span class="wheeltype"> 車輪類型: <select> <option selected="selected">默認選項</option> <option>Test1</option> </select> </span> </div> <div class="carimage"> <p><img src="../image/img-loading.gif" alt="圖片裝載中" class="carloading"></p> <p><img src="" alt="汽車圖片" class="carimg"></p> </div> </body>
body體里面囊括了3個div,第一個div的作用是顯示“數據正在裝載中…”的圖片和文字。第二個div顯示級聯下拉效果。第三個div顯示車輛圖片。
css代碼如下:
代碼清單1.2:chainSelect.css
.loading { width: 400px; margin: 0 auto; /* visibility: hidden; */ } .loading p { text-align: center; } p { margin: 0; } .car { text-align: center; } .carimage { text-align: center; } .cartype, .wheeltype, .carloading, .carimg, .car img { display: none; }
代碼清單1.3:chainSelect.js
$(document).ready(function(){ //找到三個下拉框 var carnameSelect = $(".carname").children("select"); var cartypeSelect = $(".cartype").children("select"); var wheeltypeSelect = $(".wheeltype").children("select"); carnameSelect.change(function(){ console.log("汽車廠商觸發onChange事件"); }); cartypeSelect.change(function(){ console.log("汽車類型觸發onChange事件"); }); wheeltypeSelect.change(function(){ console.log("車輪觸發onChange事件"); }); });
首先用jQuery的class選擇器選擇出三個下拉的框,當它們的值改變時觸發對應的jQuery函數,對jQuery函數的處理才是重點的內容。
首先說到jQuery中的ajax交互。前一篇我們用到get()的請求方式,今天來用以用post()方法的請求方式。
jQuery.post(url, [data], [callback], [type])
概述:
通過遠程 HTTP POST 請求載入信息.這是一個簡單的 POST 請求功
能以取代復雜ajax() 。請求成功時可調>用回調函數。如果需要在出錯時執行函數,請使用 $.ajax。
參數含義:
url:發送請求地址。
data:待發送 Key/value 參數。
callback:發送成功時回調函數。
type:返回內容格式,xml, html, script, json, text, _default。
案例如下:
代碼清單1.4:demo.js
$(document).ready(function(){ //發起ajax請求 $.post("../chainSelect", {name: "John", time: "2pm"}, function(data){ console.log("name : " + data.name); console.log("type : " + data.type); }, "json"); });
后臺Serlvet處理如下(當然你可以使用java框架,也可以使用其他后臺語言)。
代碼清單1.5:demo.java
import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ChainSelect extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("name = " + request.getParameter("name")); System.out.println("time = " + request.getParameter("time")); response.setCharacterEncoding("UTF-8"); response.setContentType("application/json; charset=utf-8"); String jsonStr = "{\"name\":\"fly\",\"type\":\"蟲子\"}"; PrintWriter out = null; try { out = response.getWriter(); out.write(jsonStr); } catch (IOException e) { e.printStackTrace(); } finally { if (out != null) { out.close(); } } } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
別忘了純Serlvet部屬要在你的web.xml做配置。我的Serlvet的完整路進地址是:http://localhost:8080/JqueryStudy/chainSelect ,兩句System.out.println()輸出ajax傳遞過來的參數name和time。response.setCharacterEncoding(“UTF-8”)的作用是告訴瀏覽器字符串為utf-8的編碼,防止中文亂碼問題。response.setContentType(“application/json; charset=utf-8”)將返回的字符串以json格式形式返回。out對象是輸出流,如果返回的是數組,格式應該如下:[“test1”, “test2”, “test3”],如果是json類,則格式如下:{“name”:”fly”,”type”:”蟲子”}。
上訴案例返回的是json對象,后臺控制臺輸出:
name = John
time = 2pm
前端瀏覽器的控制臺輸出:
name : fly
type : 蟲子
Servlet返回數組的案例如下:
代碼清單1.6:demo.java
import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ChainSelect extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("name = " + request.getParameter("name")); System.out.println("time = " + request.getParameter("time")); response.setCharacterEncoding("UTF-8"); response.setContentType("application/json; charset=utf-8"); String jsonStr = "[\"test1\", \"test2\", \"test3\"]"; PrintWriter out = null; try { out = response.getWriter(); out.write(jsonStr); } catch (IOException e) { e.printStackTrace(); } finally { if (out != null) { out.close(); } } } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
前端jQuery代碼:
$(document).ready(function(){ //發起ajax請求 $.post("../chainSelect", {name: "John", time: "2pm"}, function(data){ for(var i = 0; i < data.length; i++) { console.log((i+1) + " : " + data[i]); } }, "json"); });
后臺之需要給jsonStr賦值為數組格式而已,而前端jQuery代碼由于接收到的字符串數組,所以這里需要用遍歷數組的形式來遍歷。
本案例的Servlet代碼清單:
代碼清單1.7:ChainSelect.java
import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ChainSelect extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setCharacterEncoding("UTF-8"); response.setContentType("application/json; charset=utf-8"); String jsonStr = this.getStr(request.getParameter("keyword"), request.getParameter("type")); PrintWriter out = null; try { out = response.getWriter(); out.write(jsonStr); } catch (IOException e) { e.printStackTrace(); } finally { if (out != null) { out.close(); } } } private String getStr(String keyword, String type) { String jsonStr = ""; if("top".equals(type)) { if("BMW".equals(keyword)) { jsonStr = "[\"316ti\", \"6ercupe\"]"; } else if("Audi".equals(keyword)) { jsonStr = "[\"tt\"]"; } else if("VW".equals(keyword)) { jsonStr = "[\"Golf4\"]"; } } else if("sub".equals(type)) { if("tt".equals(keyword)) { jsonStr = "[\"rha\", \"rhb\", \"rhc\"]"; } else if("316ti".equals(keyword)) { jsonStr = "[\"rha\", \"rhb\"]"; } else if("6ercupe".equals(keyword)) { jsonStr = "[\"rha\", \"rhb\", \"rhc\"]"; } else if("Golf4".equals(keyword)) { jsonStr = "[\"rha\", \"rhb\"]"; } } return jsonStr; } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
代碼清單1.7與清單1.6的區別是,后者多了getStr()的方法,該方法用于判斷前端傳遞過來的是一級(top)下拉框的值,還是二級(sub)下拉框的值,并根據傳遞的keyword返回需要的字符串。與本后臺交互的是程序清單1.8所示的代碼。
程序清單1.8:chainSelect.js
/** * 級聯下拉框效果 */ $(document).ready(function(){ //找到三個下拉框 var carnameSelect = $(".carname").children("select"); var cartypeSelect = $(".cartype").children("select"); var wheeltypeSelect = $(".wheeltype").children("select"); carnameSelect.change(function(){ var carname = carnameSelect.val(); if(carname != "") { //汽車廠商不為空發起ajax請求 $.post("../chainSelect", {keyword: carname, type : "top"}, function(data){ if(data != null && data.length != 0) { //清除上一次change的內容 cartypeSelect.html(""); $("<option value=''>請選擇汽車類型</option>").appendTo(cartypeSelect); for(var i = 0; i < data.length; i++) { $("<option value='"+data[i]+"'>"+data[i]+"</option>").appendTo(cartypeSelect); } $(".cartype").show(); carnameSelect.next("img").show(); } }, "json"); } else { //3.如果值為空,那么第二個下拉框所在span要隱藏起來,第一個下拉框后面的指示圖片也要隱藏 $(".cartype").hide(); $(".wheeltype").hide(); $(".carimage").hide(); $(this).next("img").hide(); } }); cartypeSelect.change(function(){ var cartype = cartypeSelect.val(); if(cartype != "") { //汽車類型不為空發起ajax請求 $.post("../chainSelect", {keyword: cartype, type : "sub"}, function(data){ if(data != null && data.length != 0) { //清除上一次change的內容 wheeltypeSelect.html(""); $("<option value=''>請選擇車輪類型</option>").appendTo(wheeltypeSelect); for(var i = 0; i < data.length; i++) { $("<option value='"+data[i]+"'>"+data[i]+"</option>").appendTo(wheeltypeSelect); } $(".wheeltype").show(); cartypeSelect.next("img").show(); } }, "json"); } else { //汽車類型為空 $(".wheeltype").hide(); $(".carimage").hide(); $(this).next("img").hide(); } }); wheeltypeSelect.change(function(){ //選中的車輪類型 var wheeltype = wheeltypeSelect.val(); if(wheeltype != "") { //選中的車輛廠商 var carname = carnameSelect.val(); //選中的車輛類型 var cartype = cartypeSelect.val(); //圖片的名稱 var carimgName = carname + "_" + cartype + "_" + wheeltype + ".jpg"; console.log("carimgName : " + carimgName); $(".carimage").show(); $(".carimg").attr("src", "../image/" + carimgName).load(function(){ //隱藏loading圖片 $(".carloading").hide("slow"); }); $(".carimage p img").show("slow"); } else { // alert("內容為空"); // $("img").hide(); $(".carimage").hide(); } }); //給數據裝載中的節點定義ajax事件,實現動畫提示效果 $(".loading").ajaxStart(function(){ $(this).css("visibility", "visible"); $(this).animate({ opacity: 1 },0); }).ajaxStop(function(){ $(this).animate({ opacity: 0 },500); }); });
jQuery代碼的思路是,用class選擇器選擇出三個下拉框,賦值給變量carnameSelect,cartypeSelect,wheeltypeSelect,默認carnameSelect下拉框是顯示的,其他下拉框是隱藏。然后給他們三者注冊change()事件,當用戶選擇下拉框的值的時候執行事件函數體里面的內容。這里我以第一級下拉框為例來講解處理的過程。如果用戶選擇了第一級下拉框”汽車廠商”的”寶馬”,則執行如下代碼:
carnameSelect.change(function(){ var carname = carnameSelect.val(); if(carname != "") { //汽車廠商不為空發起ajax請求 $.post("../chainSelect", {keyword: carname, type : "top"}, function(data){ if(data != null && data.length != 0) { //清除上一次change的內容 cartypeSelect.html(""); $("<option value=''>請選擇汽車類型</option>").appendTo(cartypeSelect); for(var i = 0; i < data.length; i++) { $("<option value='"+data[i]+"'>"+data[i]+"</option>").appendTo(cartypeSelect); } $(".cartype").show(); carnameSelect.next("img").show(); } }, "json"); } else { //3.如果值為空,那么第二個下拉框所在span要隱藏起來,第一個下拉框后面的指示圖片也要隱藏 $(".cartype").hide(); $(".wheeltype").hide(); $(".carimage").hide(); $(this).next("img").hide(); } });
先將第一級下拉框內容取出來,如果值為空,那么第二個下拉框所在span要隱藏起來,第一個下拉框后面的指示圖片也要隱藏。如果有內容, 則用該行代碼$.post(“../chainSelect”, {keyword: carname, type : “top”}, function(data){}, “json”)向上訴的Serlvet發起post請求,post的第一個參數是Serlvet的后臺地址,第二個參數畫括號括起來的json數據,第三個參數是回調函數,第四個參數”json”表明發送的json數據。在回調函數中,參數data接收Serlvet返回的值,由于Serlvet返回的是可以解析為字符串數組的數據,所以用for循環來遍歷得到的數據,并生成option新節點appenTo()插入到select之后。
程序清單1.8中,值得注意的地方還有$(“.loading”).ajaxStart(function(){}).ajaxStop(function(){}),這是為了美化汽車圖片加載的代碼。這里用到jQuery的動畫專用效果的animate(),使程序淡入淡出更加的和諧。
到此幾乎把級聯效果實現了,但是如果在高并發環境下,每次用戶切換選項都向服務器發送請求,服務器的壓力可能過大。所以這里我們用jQuery的緩存來保存那些已經緩存過的請求。可以使用jQuery的data()方法。
定義和用法
從被選元素中返回附加的數據。
$(selector).data(name)
name 可選。規定要取回的數據的名稱。
如果沒有規定名稱,則該方法將以對象的形式從元素中返回所有存儲的數據。
向元素附加數據
$(selector).data(name,value)
name 必需。規定要設置的數據的名稱。
value 必需。規定要設置的數據的值。
data()的使用案例如程序清單1.9:
<html> <head> <script type="text/javascript" src="/jquery/jquery.js"></script> <script type="text/javascript"> $(document).ready(function(){ $("#btn1").click(function(){ $("div").data("greeting", "Hello World"); }); $("#btn2").click(function(){ alert($("div").data("greeting")); }); }); </script> </head> <body> <button id="btn1">把數據添加到 div 元素</button><br /> <button id="btn2">獲取已添加到 div 元素的數據</button> <div></div> </body> </html>
加上緩存之后的完整jQuery代碼如下程序清單。
程序清單2.0:chainSelect.js
/** * 級聯下拉框效果 */ $(document).ready(function(){ //找到三個下拉框 var carnameSelect = $(".carname").children("select"); var cartypeSelect = $(".cartype").children("select"); var wheeltypeSelect = $(".wheeltype").children("select"); carnameSelect.change(function(){ var carname = carnameSelect.val(); if(carname != "") { if (!carnameSelect.data(carname)) { //汽車廠商不為空發起ajax請求 $.post("../chainSelect", {keyword: carname, type : "top"}, function(data){ if(data != null && data.length != 0) { //清除上一次change的內容 cartypeSelect.html(""); $("<option value=''>請選擇汽車類型</option>").appendTo(cartypeSelect); for(var i = 0; i < data.length; i++) { $("<option value='"+data[i]+"'>"+data[i]+"</option>").appendTo(cartypeSelect); } $(".cartype").show(); carnameSelect.next("img").show(); } //將data放入緩存 carnameSelect.data(carname, data); }, "json"); } else { //從緩存中取出數據 var data = carnameSelect.data(carname); if(data != null && data.length != 0) { //清除上一次change的內容 cartypeSelect.html(""); $("<option value=''>請選擇汽車類型</option>").appendTo(cartypeSelect); for(var i = 0; i < data.length; i++) { $("<option value='"+data[i]+"'>"+data[i]+"</option>").appendTo(cartypeSelect); } $(".cartype").show(); carnameSelect.next("img").show(); } } } else { //3.如果值為空,那么第二個下拉框所在span要隱藏起來,第一個下拉框后面的指示圖片也要隱藏 $(".cartype").hide(); $(".wheeltype").hide(); $(".carimage").hide(); $(this).next("img").hide(); } }); cartypeSelect.change(function(){ var cartype = cartypeSelect.val(); if(cartype != "") { if(!cartypeSelect.data(cartype)) { //汽車類型不為空發起ajax請求 $.post("../chainSelect", {keyword: cartype, type : "sub"}, function(data){ if(data != null && data.length != 0) { //清除上一次change的內容 wheeltypeSelect.html(""); $("<option value=''>請選擇車輪類型</option>").appendTo(wheeltypeSelect); for(var i = 0; i < data.length; i++) { $("<option value='"+data[i]+"'>"+data[i]+"</option>").appendTo(wheeltypeSelect); } $(".wheeltype").show(); cartypeSelect.next("img").show(); } cartypeSelect.data(cartype, data); }, "json"); } else { var data = cartypeSelect.data(cartype); if(data != null && data.length != 0) { //清除上一次change的內容 wheeltypeSelect.html(""); $("<option value=''>請選擇車輪類型</option>").appendTo(wheeltypeSelect); for(var i = 0; i < data.length; i++) { $("<option value='"+data[i]+"'>"+data[i]+"</option>").appendTo(wheeltypeSelect); } $(".wheeltype").show(); cartypeSelect.next("img").show(); } } } else { //汽車類型為空 $(".wheeltype").hide(); $(".carimage").hide(); $(this).next("img").hide(); } }); wheeltypeSelect.change(function(){ //選中的車輪類型 var wheeltype = wheeltypeSelect.val(); if(wheeltype != "") { //選中的車輛廠商 var carname = carnameSelect.val(); //選中的車輛類型 var cartype = cartypeSelect.val(); //圖片的名稱 var carimgName = carname + "_" + cartype + "_" + wheeltype + ".jpg"; $(".carimage").show(); //通過Javascript中的Image對象預裝載圖片 var cacheimg = new Image(); $(cacheimg).attr("src", "../image/" + carimgName).load(function(){ //隱藏loading圖片 $(".carloading").hide("slow"); $(".carimg").attr("src", "../image/" + carimgName); }); $(".carimage p img").show("slow"); } else { $(".carimage").hide(); } }); //給數據裝載中的節點定義ajax事件,實現動畫提示效果 $(".loading").ajaxStart(function(){ $(this).css("visibility", "visible"); $(this).animate({ opacity: 1 },0); }).ajaxStop(function(){ $(this).animate({ opacity: 0 },500); }); });
用了data()之后,當用戶選擇了下拉框,并不是直接奔著服務器請求而去的,而是先判斷緩存是否為空,carnameSelect.data(carname)。如果為空,則發起ajax請求,并將返回的結果放進緩存carnameSelect.data(carname, data)。如果不為空,在循環添加option節點之前data從緩存中拿到var data = carnameSelect.data(carname)。同樣的,圖片的緩存放進我們的Image對象中var cacheimg = new Image(),這行代碼往后的第一行和第四行將緩存中的圖片取出并顯示出來。
關于“jQuery如何實現級聯下拉框”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。