1. 程式人生 > 實用技巧 >Ajax&jQuery

Ajax&jQuery

Ajax&jQuery

1.Ajax

Asynchronous JavaScript and XML(非同步的 JavaScript 和 XML),不是新的程式語言,而是一種使用現有標準的新方法。

AJAX 最大的優點是在不重新載入整個頁面的情況下,可以與伺服器交換資料並更新網頁上的區域性內容。

AJAX 不需要任何瀏覽器外掛,但需要使用者允許JavaScript在瀏覽器上執行。

1.1XMLHttpRequest物件

XMLHttpRequest物件用於和伺服器交換資料。

  • 建立XMLHttpRequest物件
var xmlhttp;
if (window.XMLHttpRequest){
    //  IE7+, Firefox, Chrome, Opera, Safari 瀏覽器執行程式碼
    xmlhttp=new XMLHttpRequest();
}else{
    // IE6, IE5 瀏覽器執行程式碼
    xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}

XMLHttpRequest的常用方法:

  • open(method,url,async)

    XMLHttpRequest.open(method,url,async):規定請求的型別、URL 以及是否非同步處理請求。
    method:"GET":get請求;"POST":post請求
    url:"/Demo2/AjaxDemoServlet?id=1",請求地址路徑
    async:true:非同步請求;false:同步請求

  • send(string)

    XMLHttpRequest.send(String):將請求傳送到伺服器。

    ​ String僅針對post請求,get請求不能攜帶String。

  • setRequestHeader(header,value)

    xmlHttpRequest.setRequestHeader(header,value):向請求新增HTTP頭。

    如果需要像 HTML 表單那樣 POST 資料,請使用 setRequestHeader() 來新增 HTTP 頭。然後在 send() 方法中規定您希望傳送的資料:

    xmlHttpRequest.setRequestHeader("Content-type","application/x-www-form-urlencoded");
    xmlHttpRequest.send("id=1&name=wang");
    

1.2伺服器響應

使用 XMLHttpRequest 物件的 responseText 或 responseXML 屬性來獲取伺服器的響應。

  • responseText:獲得字串形式的響應資料。
  • responseXML:獲得 XML 形式的響應資料。

1.3onreadystatechange事件

用於執行一些基於響應的任務,當readyState改變時,就會觸發onreadystatechange事件。

下面是 XMLHttpRequest 物件的三個重要的屬性:

當 readyState 等於 4 且狀態為 200 時,表示響應已就緒。

1.4Ajax執行Get請求

  • 不獲取響應資料
<script>
      function getDemo() {
          //1.建立XMLHttpRequest物件
          var xmlHttpRequest=new XMLHttpRequest();

          //2.向伺服器傳送Get請求
          xmlHttpRequest.open("GET","/Demo2/AjaxDemoServlet?id=1",true);
    	  //將請求傳送到伺服器
          xmlHttpRequest.send();
      }
</script>
  • 獲取響應資料
<script>
      function getDemo() {
          var xmlHttpRequest=new XMLHttpRequest();
          //3.註冊監聽,以便獲取響應資料
          xmlHttpRequest.onreadystatechange=function () {         if(xmlHttpRequest.readyState==4&&xmlHttpRequest.status==200){
                  alert(xmlHttpRequest.responseText);
              }
          }
          xmlHttpRequest.open("GET","/Demo2/AjaxDemoServlet?id=1",true);
          xmlHttpRequest.send();
      }

響應資料:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("收到一個get請求,id為"+request.getParameter("id"));
        response.setContentType("text/html;charset=utf-8");
        response.getWriter().write("收到了get請求");
    }

1.5Ajax執行Post請求

  • 不獲取響應資料
function postDemo() {
    	  //1.建立XMLHttpRequest物件
          var xmlHttpRequest=new XMLHttpRequest();
          //2.向伺服器傳送Post請求 
    xmlHttpRequest.open("POST","/Demo2/AjaxDemoServlet",true);
          //向請求新增新增http頭,表示像html表單那樣post資料
          xmlHttpRequest.setRequestHeader("Content-type","application/x-www-form-urlencoded");
    	 //將請求傳送到伺服器
          xmlHttpRequest.send("id=1&name=wang");
      }
  • 獲取響應資料
 function postDemo() {
          var xmlHttpRequest=new XMLHttpRequest();
		 //獲取響應資料
          xmlHttpRequest.onreadystatechange=function(){
           if(xmlHttpRequest.readyState==4&&xmlHttpRequest.status==200){
                  alert(xmlHttpRequest.responseText);
              }
          }
          xmlHttpRequest.open("POST","/Demo2/AjaxDemoServlet",true);
          xmlHttpRequest.setRequestHeader("Content-type","application/x-www-form-urlencoded");
          xmlHttpRequest.send("id=1&name=wang");
      }

響應資料:

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("收到一個post請求,id為"+request.getParameter("id")+",name為"+request.getParameter("name"));
        response.setContentType("text/html;charset=utf-8");
        response.getWriter().write("收到了post請求");
    }

1.6案例:Ajax校驗使用者名稱是否可用

  • register_Ajax.jsp
<head>
    <title>使用者註冊頁面</title>
    <script>
        function checkUsername() {
            var xmlHttpRequest=new XMLHttpRequest();
            var username=document.getElementById("name").value;
            xmlHttpRequest.onreadystatechange=function () {
                if(xmlHttpRequest.readyState==4&&xmlHttpRequest.status==200){
                    var data=xmlHttpRequest.responseText;
                    if(data==0){
                        document.getElementById("span1").innerHTML="<font color='red'>使用者名稱已被佔用</font>"
                    }else if(data==1){
                        document.getElementById("span1").innerHTML="<font color='green'>使用者名稱可用</font>"
                    }
                }
            }
            xmlHttpRequest.open("GET","/Demo2/CheckUsernameServlet?username="+username,true);
            xmlHttpRequest.send();
        }
    </script>
</head>
<body>
    <form action="RegisterServlet" method="post">
        請輸入使用者名稱:<input type="text" name="username" id="name" onblur="checkUsername()"/><span id="span1"></span><br/>
        請輸入密碼:<input type="text" name="password"/><br/>
        <input type="submit" value="註冊"/>
    </form>
</body>

注意:獲取id為name的元素的值要用document.getElementById("name").value,而不是document.getElementById("name")。

用document.getElementById("name")獲取的是元素,而不是值,如下圖:

  • CheckUsernameServlet
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String username = request.getParameter("username");
        response.setContentType("text/html;charset=utf-8");
        if(username.equals("COCO")){
           // response.getWriter().write(0);
            response.getWriter().print(0);
        }else {
            //response.getWriter().write(1);
            response.getWriter().print(1);
        }
    }

注意:這裡返回int只能用print或println,write只能寫字元型,即char,而且數字傳到前端會產生亂碼,如下:

  • write和print方法比較:

write():僅支援輸出字元型別資料,字元、字元陣列、字串等;
print():可以將各種型別(包括Object)的資料通過預設編碼轉換成bytes位元組形式,這些位元組都通過write(int c)方法被輸出。

2.jQuery

jQuery是一個JavaScript庫,可以極大簡化Javascript程式設計。

2.1安裝jQuery

  • 下載後安裝jQuery

將jquery-1.11.3.min.js拷貝到工程目錄中,如web/js/jquery-1.11.3.min.js,然後在頁面上引用:

<script src="js/jquery-1.11.3.min.js"></script>
是否疑惑為什麼沒有在 <script> 標籤中使用 type="text/javascript"?因為在HTML5中,不必那樣做了。JavaScript 是HTML5以及所有現代瀏覽器中的預設指令碼語言。
  • CDN引用

如果不希望下載並存放 jQuery,那麼也可以通過 CDN(內容分發網路) 引用它。Staticfile CDN、百度、又拍雲、新浪、谷歌和微軟的伺服器都存有 jQuery 。

百度CDN:

<script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js">

又拍雲CDN:

<script src="https://upcdn.b0.upaiyun.com/libs/jquery/jquery-2.0.2.min.js">

2.2jQuery選擇器

  • 元素選擇器

    基於元素名選取元素。

    $("button"):在頁面獲取所有的<button>元素。

  • id選擇器

    通過元素的id屬性選取指定的元素。

    $("#id2"):獲取id為id2的元素。

  • 類選擇器

    通過指定的class屬性查詢元素。

    $(".test"):查詢帶有class="test"屬性的元素。

2.3jQuery設定內容

  • text()

    設定或返回所選元素的文字內容,兩個標籤中寫值,如<textarea id="id3"></textarea>

  • html()

    設定或返回元素的內容(包括html標記)。

  • val()

    設定或返回表單欄位的值,用於元素裡面有value屬性的。

2.4jQuery常用方法

2.4.1load()方法

load()方法從伺服器載入資料,並把返回的資料放入被選元素中。

語法:

$(selector).load(URL,data,callback);
/*
必需的 URL 引數規定您希望載入的 URL。
可選的 data 引數規定與請求一同傳送的查詢字串鍵/值對集合。
可選的 callback 引數是 load() 方法完成後所執行的函式名稱。
*/
2.4.1.1load()方法演示
  • jQueryServlet
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("收到一個請求");
        response.setContentType("text/html;charset=utf-8");
        response.getWriter().write("執行load方法");
    }
  • jQueryDemo.jsp
<head>
    <title>Title</title>
    <script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
    <script>
        function loadDemo() {
            $("#id2").load("/Demo2/jQueryServlet",function (responseTxt,statusTxt,xhr){
                $("#id2").val(responseTxt);//將響應回的資料放入到id為id2的元素中
            });
        }
    </script>
</head>
<body>
    <a href="" onclick="loadDemo()" id="id1">使用jQuery執行load方法</a><br/>
    <input type="button" value="使用jQuery執行load方法" onclick="loadDemo()"/>
    <input type="text" id="id2"/>
</body>

注意:

如果用超連結:

<a href="" onclick="loadDemo()" id="id1">使用jQuery執行load方法</a><br/>

響應回的資料會在id2中一閃而過,原因是有兩次重新整理,先走 onClick的方法,取到資料回來之後,賦值顯示。接著走 href=""的路徑,但是這個屬性沒有給值,所以會把當前的頁面重新再重新整理一次,導致看不見值。

2.4.2get()方法

$.get() 方法通過 HTTP GET 請求從伺服器上請求資料。

語法:

$.get(url,callback);

必需的url引數規定希望請求的URL。

可選的callback引數是請求成功後所執行的函式名。

2.4.2.1get()方法演示
    <script>
        $(document).ready(function () {
            $("button").click(function () {//即點選button後執行get請求
                $.get("/Demo2/jQueryServlet",function (data,status) {
                    $("#id2").val(data);//將返回的資料填入id2
                    $("#id3").text(data);
                });
            });
        })
    </script>
<body>
    <button>演示get</button><br/>
    <input type="text" id="id2"/>
    <textarea id="id3"></textarea>
</body>

2.4.3post()方法

$.post() 方法通過 HTTP POST 請求從伺服器上請求資料。

語法:

$.post(url,data,callback);

必需的url引數規定您希望請求的url。

可選的data引數規定連同請求傳送的資料。

可選的callback引數是請求成功後所執行的函式名。

2.4.3.1post()方法演示
<script>
    $(document).ready(function () {
                $("button").click(function () {
                    $.post("/Demo2/jQueryServlet",{name:"wanger",age:19},
                           function (data,status) {
                       		 $("#id2").val(data+"\\"+status);
                   		 });
                });
    })
</script>	
<body>
    <button>演示post</button><br/>
	<input type="text" id="id2"/>
</body>

2.5案例1:jQuery校驗使用者名稱是否可用

  • register_jQuery.jsp
    <script>
        function checkUsername() {
            //var username=document.getElementById("name").value;
            var username=$("#name").val();//以jQuery方式獲取使用者名稱
            $.post("/Demo2/jQueryServlet",{name:username},function (data,status) {
                if(data==0){
                    $("#span1").html("<font color='red'>使用者名稱已被佔用</font>");
                }else{
                    $("#span1").html("<font color='green'>使用者名稱可用</font>");
                }
            })
        }
    </script>
<body>
    <form action="RegisterServlet" method="post">
        請輸入使用者名稱:<input type="text" name="username" id="name" onblur="checkUsername()"/><span id="span1"></span><br/>
        請輸入密碼:<input type="text" name="password"/><br/>
        <input type="submit" value="註冊"/>
    </form>
</body>

2.6案例2:jQuery實現仿百度提示

效果如下:

  • HeimaSearch.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>黑馬搜尋</title>
    <script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
    <script>
        /*文件就緒程式碼:$(document).ready(function () {})可簡寫為$(function(){})*/
        $(function () {
            $("#search").keyup(function () {
                //var search=$("#search").val();
                var search=$(this).val();//this即為執行此方法的物件:$("#search");
                if(search!=""){//當輸入框不為空時才傳送請求
                    $.post("/StuSysMvc/HeimaSearchServlet",{searchValue:search},function(data,status){
                        if(data!=""){
                            $("#div01").show();//當返回值不為空時才展示搜尋提示框
                            $("#div01").html(data);
                        }else{
                            $("#div01").hide();//非第一次時返回值為空時隱藏搜尋提示框
                        }
                    })
                }else{
                    $("#div01").hide();//刪除搜尋內容後要隱藏搜尋提示框
                }
            })
        })
    </script>
</head>
<body>
    <center >
        <br/><br/><br/><br/><br/><br/>
        <h2>Heima黑馬</h2>
        <input type="text" name="search" id="search" onkeyup="initSearch()" style="width: 600px ; height: 55px  ;font-size: 20px;"/>
        <input type="button" value="黑馬一下"  style="height: 55px ; width: 100px ; ">
        <div id="div01" style="position:relative; left : -52px; width: 600px;  border:  1px solid blue; display: none;"></div>
        <%--
    		display:none搜尋框預設不顯示;
    		div01這個div不指定高度,而是根據返回的list.jsp中的資料動態調整。
        --%>
    </center>
</body>
</html>
  • HeimaSearchServlet
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        String searchValue = request.getParameter("searchValue");
        System.out.println("收到請求:"+searchValue);
        StudentService studentService=new StudentServiceImpl();
        List<Student> list=studentService.initSearch(searchValue);//dao層可設定預設最多隻查詢10條
        request.setAttribute("list",list);
        request.getRequestDispatcher("list.jsp").forward(request,response);
        //響應list.jsp頁面給請求者。請求:瀏覽器請求,瀏覽器看到這個jsp頁面
    }
  • list.jsp

    在list.jsp頁面遍歷list,HeimaSearchServlet將list.jsp返回給請求者。

<table width="100%"><%--設定此table和div同寬,使結果左對齊--%>
    <c:forEach var="stu" items="${list}">
        <tr>
            <td>${stu.sname}</td>
        </tr>
    </c:forEach>
</table>

2.7案例3:jQuery實現省市聯動

2.7.1資料庫準備

準備兩張表:province和city,給city表的c_pid欄位新增外來鍵約束指向province表的唯一索引:主鍵pid。

2.7.2使用xml傳輸資料

  • 依賴jar包

  • proCity_xml.jsp

<script>
        $(function () {
            $("#province").change(function () {
                var choice=$(this).val();
                if(choice!=""){
                    $.post("/StuSysMvc/ProCityServlet",{province:choice},function (data,status) {
                        $("#city").html("<option value=''>--請選擇--</option>");//清空city中的option
                        //從data資料裡找出所有的city,然後遍歷所有的city,每遍歷一個city就執行一次function方法
                        /*<list>
                            <city>
                                <cid>1<id>
                                <cname>鄭州</cname>
                                <cPid>1</cPid>
                            </city>
                            ......
                        </list>*/
                        $(data).find("city").each(function () {
                            var cid=$(this).children("cid").text();
                            var cname=$(this).children("cname").text();
                            $("#city").append("<option value='"+cid+"'>"+cname+"</option>");
                        })
                    })
                }
            });
        });
    </script>
</head>
<body>
    省份:<select name="province" id="province">
            <option value="">--請選擇--</option>
            <option value="1">河南</option>
            <option value="2">廣東</option>
         </select>
    城市:<select name="city" id="city">
            <option value="">--請選擇--</option>
         </select>
</body>
  • ProCityServlet
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Integer pid = Integer.parseInt(request.getParameter("province"));
        StudentService studentService=new StudentServiceImpl();
        List<City> list = studentService.findCityByPid(pid);
        //返回資料
        //可以像仿百度提示那樣返回html,但最好採用返回xml或json
        //1.返回xml
        XStream xStream=new XStream();
        //xStream.useAttributeFor(City.class,"cid");//將cid設定為city的屬性,寫在設定別名前後均可
        xStream.alias("city",City.class);
        //xStream.useAttributeFor(City.class,"cid");
        String s = xStream.toXML(list);
        response.setContentType("text/xml;charset=utf-8");//注意這裡是xml
        response.getWriter().write(s);
    }

xml資料如下:

修改別名:將com.itheima.entity.City改為city,並將cid設定為city的屬性:

2.7.3使用json傳輸資料

  • 依賴jar包:

  • proCity_json.jsp

    <script>
        $(function () {
            $("#province").change(function () {
                var choice=$(this).val();
                if(choice!=""){
                    $.post("/StuSysMvc/ProCityServlet",{province:choice},function (data,status) {
                        $("#city").html("<option value=''>--請選擇--</option>");
                        /*data:
                        [
                            {
                                "cPid":2,
                                "cid":5,
                                "cname":"廣州"
                            },
                           ...
                        ]
                         */
                        //先遍歷,再追加
                        $(data).each(function (index,c) {//index:索引;c:遍歷到的元素
                            $("#city").append("<option value='"+c.cid+"'>"+c.cname+"</option>")
                        })
                    },"json")//最後一個引數為dataType,指定資料型別為json,預設智慧判斷(xml,json,script,html),但json資料不能識別出來,需要宣告一下
                }
            });
        });
    </script>
  • ProCityServlet
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Integer pid = Integer.parseInt(request.getParameter("province"));
        StudentService studentService=new StudentServiceImpl();
        List<City> list = studentService.findCityByPid(pid);
        //返回資料
        //2.返回Json
        JSONArray jsonArray = JSONArray.fromObject(list);
        /*
        JSONArray:轉化為json陣列:[{"cPid":2,"cid":5,"cname":"廣州"},{"cPid":2,"cid":6,"cname":"東莞"},{"cPid":2,"cid":7,"cname":"深圳"},{"cPid":2,"cid":8,"cname":"江門"}]
        JSONObject:轉化為接送資料:{"cPid":2,"cid":5,"cname":"廣州"}
         */
        String s = jsonArray.toString();
        System.out.println(s);
        response.setContentType("text/html;charset=utf-8");
        response.getWriter().write(s);*/
    }