zoukankan      html  css  js  c++  java
  • 《锋利的JQuery》读书要点笔记5——jQuery与Ajax的应用

    第6章 jQuery与Ajax的应用

    Ajax的全称:Asynchronous JavaScript and XML (异步Javascript和XML)

    传统模式中,数据提交通过表单方式实现,数据的获取是靠全页面刷新来重新获取整页的内容。而Ajax模式只是通过XMLHttpRequest对象向服务器端提交数据,即按需发送。因为Ajax需要与Web服务器端进行交互,所以用个服务器,我这里用的是Tomcat。


     1. 传统Js的Ajax操作

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
    <title></title>
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <script language="javascript" type="text/javascript">
    //通过这个函数来异步获取信息
    function Ajax(){ 
        var xmlHttpReq = null;    //声明一个空对象用来装入XMLHttpRequest
        if (window.ActiveXObject){//IE5 IE6是以ActiveXObject的方式引入XMLHttpRequest的
            xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
        } 
        else if (window.XMLHttpRequest){//除IE5 IE6 以外的浏览器XMLHttpRequest是window的子对象
            xmlHttpReq = new XMLHttpRequest();//实例化一个XMLHttpRequest
        }
        if(xmlHttpReq != null){    //如果对象实例化成功 
            xmlHttpReq.open("GET","test.jsp",true);    //调用open()方法并采用异步方式
            xmlHttpReq.onreadystatechange=RequestCallBack; //设置回调函数
            xmlHttpReq.send(null);    //因为使用get方式提交,所以可以使用null参调用
        }
        function RequestCallBack(){//一旦readyState值改变,将会调用这个函数
            if(xmlHttpReq.readyState == 4){//readyState的值为4表示请求完成加载(即请求发出去了)
                    if(xmlHttpReq.status == 200){//HTTP状态为200表示相服务器应成功
                        //将xmlHttpReq.responseText的值赋给ID为 resText 的元素
                        document.getElementById("resText").innerHTML = xmlHttpReq.responseText;
                    }
            }
        }
    }
    </script>
    </head>
    <body>
    <input type="button" id="" value="Ajax提交" onclick="Ajax();" />
    <div id="resText" ></div>
    </body>
    </html>

    2. jQuery中的Ajax 

     $.ajax(); $.load(); $.get(); $.post(); $.getStript(); $.getJSON() 这几个常用的方法。

    $.load()方法: 将远程的HTML载入并插入DOM中。

    首先构建一个test.html:

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <title></title>
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    </head>
    <body>
    <div class="comment">
     <h6>张三:</h6>
     <p class="para">沙发.</p>
    </div>
    <div class="comment">
     <h6>李四:</h6>
     <p class="para">板凳.</p>
    </div>
    <div class="comment">
     <h6>王五:</h6>
     <p class="para">地板.</p>
    </div>
    </body>
    </html>

    然后用load()方法将它插入到另一个页面中:

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <title></title>
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <style>
    * { margin:0; padding:0;}
    body { font-size:12px;}
    .comment { margin-top:10px; padding:10px; border:1px solid #ccc;background:#DDD;}
    .comment h6 { font-weight:700; font-size:14px;}
    .para { margin-top:5px; text-indent:2em;background:#DDD;}
    </style>
     <!--   引入jQuery -->
    <script src="../scripts/jquery.js" type="text/javascript"></script>
    <script language="javascript" type="text/javascript">
      $(function(){
          $("#send").click(function(){
                  $("#resText").load("test.html");
          })
      })
    </script>
    </head>
    <body>
    <input type="button" id="send" value="Ajax获取" />
    
    <div  class="comment">
        已有评论:
    </div>
    <div id="resText" ></div>
    </body>
    </html>

     自己第一遍写的时候忘记了基本的事:对于jQuery来说,为页面元素添加事件要在DOM初始完成之后再操作,即$(document).ready(......);

       

    load()方法里的第三个参数是个回调函数,这个函数有3个参数,分别代表请求返回的内容,请求状态和XMLHttpRequest对象

    $("#resText").load("test.html .para",function (responseText, textStatus, XMLHttpRequest){
                             alert( $(this).html() );    //在这里this指向的是当前的DOM对象,即 $("#iptText")[0]
                             alert(responseText);       //请求返回的内容
                             alert(textStatus);            //请求状态:success,error
                             alert(XMLHttpRequest);     //XMLHttpRequest对象
                }); 

    $.get()方法和$.post()方法

     分别使用get方式和post方式来进行异步请求。

    注意上面的回调函数是只有当请求成功时才会被调用,这点和$.load()的回调函数不一样。面是一个评论页面的HTML的代码,来说明$.get()方法的使用。

    <form id="form1">
    <p>评论:</p>
     <p>姓名: <input type="text" name="username" id="username" /></p>
     <p>内容: <textarea name="content" id="content" ></textarea></p>
     <p><input type="button" id="send" value="提交"/></p>
    </form>
    
    
    <div  class='comment'>已有评论:</div>
    <div id="resText" >
    </div>

    实现点击提交按钮后将评论显示在已有评论下方:

    $(function(){
           $("#send").click(function(){
                $.get("get1.jsp", { //使用$get()方法异步请求,第一个参数是请求页面的URL地址,第二个是发送至服务器的data,第三个是回调函数
                            username :  encodeURI( $("#username").val() ) , 
                            content :   encodeURI( $("#content").val() ) 
                        }, function (data, textStatus){ //第一个参数是返回的内容,第二个是请求状态
                            $("#resText").html(  decodeURI(data) ); // 把返回的数据添加到页面上
                        }
                );
           })
        })

    Js的encodeURI()和decodeURI() 方法,encodeURI() 函数可把字符串作为 URI 进行编码。对以下在 URI 中具有特殊含义的 ASCII 标点符号,encodeURI() 函数是不会进行转义的: , / ? : @ & = + $ #

    decodeURI() 函数可对 encodeURI() 函数编码过的 URI 进行解码。


     数据格式:HTML片段、XML文档(jQuery的DOM处理也可用于XML文档)、JSON

    jQuery解析XML文档:

    $(function(){
           $("#send").click(function(){
                $.get("get2.jsp", { 
                            username :  encodeURI( $("#username").val() ) , 
                            content :   encodeURI( $("#content").val() ) 
                        }, function (data, textStatus){
                            var username = $(data).find("comment").attr("username");
                            var content = $(data).find("comment content").text();
                            username =  decodeURI(username);
                            content = decodeURI(content);
                            var txtHtml = "<div class='comment'><h6>"+username+":</h6><p class='para'>"+content+"</p></div>";
                            $("#resText").html(txtHtml); // 把返回的数据添加到页面上
                        });
           })
        })

     jQuery解析JSon:

    $(function(){
           $("#send").click(function(){
                $.get("get3.jsp", { 
                            username :  encodeURI( $("#username").val() ) , 
                            content :   encodeURI( $("#content").val() ) 
                        }, function (data, textStatus){
                            var username = data.username;
                            var content = data.content;
                            username =  decodeURI(username);
                            content = decodeURI(content);
                            var txtHtml = "<div class='comment'><h6>"+username+":</h6><p class='para'>"+content+"</p></div>";
                            $("#resText").html(txtHtml); // 把返回的数据添加到页面上
                        },"json");
           })
        })

     

    $.getScript()和$.getJson()方法

    $.getScript()用来加载js文件,它也有回调函数,在js文件加载成功后运行。

    $.getJson()方法用于加载json文件,用法和$.getScript()相同。

     可以通过JSONP形式的回调函数来加载其它网站的JSON数据,关于JSON和JSONP。例如从图片网站Flickr搜索4张汽车图片:

      <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
    <title></title>
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <style>
    * { margin:0; padding:0;}
    body { font-size:12px;}
    .para { 
    width:100px;
    height:100px;
    margin:5px;
    border:0;
    }
    </style>
     <!--   引入jQuery -->
    <script src="../scripts/jquery.js" type="text/javascript"></script>
     <script>
       $(function(){
            $('#send').click(function() {
                $.getJSON("http://api.flickr.com/services/feeds/photos_public.gne?tags=car&tagmode=any&format=json&jsoncallback=?",
                          function(data){
                              $.each(data.items, function( i,item ){
                                    $("<img class='para'/> ").attr("src", item.media.m ).appendTo("#resText");
                                    if ( i == 3 ) { 
                                        return false;
                                    }
                              });
                         }
                ); 
           })
       })
       </script>
    </head>
    <body>
    
     <p>
    <input type="button" id="send" value="加载"/>
     </p>
    
     <div id="resText" >
        
     </div>
    
    </body>
    </html>

     关于遍历用的$.each()函数:以一个数组或者对象作为第一个参数,以一个回调函数作为第二个参数。回调函数有两个参数,第一个是对象的成员或者数组的索引,第二个是对应变量或内容。


    $.ajax()方法:jQuery最底层ajax的实现。

    <!-- $.ajax()方法代替$.getScript()方法 -->
     <script>
       $(function(){
            $('#send').click(function() {
                $.ajax({
                  type: "GET",
                  url: "test.js",
                  dataType: "script"
                }); 
            });
       })
       </script>
    <!-- $.ajax()方法代替$.getJson()方法 -->
     <script>
       $(function(){
            $('#send').click(function() {
                $.ajax({
                  type: "GET",
                  url: "test.json",
                  dataType: "json",
                  success : function(data){
                         $('#resText').empty();
                          var html = '';
                          $.each( data  , function(commentIndex, comment) {
                              html += '<div class="comment"><h6>' + comment['username'] + ':</h6><p class="para">' + comment['content'] + '</p></div>';
                          })
                         $('#resText').html(html);
                  }
                }); 
            });
       })
       </script>

    2. 序列化元素

     

    其余需要注意的方法是:serializaArray()方法,作用于DOM对象而不是全局函数,将DOM元素序列化后,返回JSON数据的格式。eg:

    $(function(){
             var fields = $(":checkbox,:radio").serializeArray();
             console.log(fields);// Firebug输出
             $.each( fields, function(i, field){
                $("#results").append(field.value + " , ");
            }); 
       })

     $.param()方法,用来对一个数组或对象按照key/value进行序列化。


     3. jQuery中的ajax全局事件

    使某个Ajax请求不受全局方法影响。


     4. 实战案例——基于jQuery的Ajax聊天室程序

    Mysql建表,这里navicat建表的话字段名和表名不要加什么双引号之类的,否则报错。

    CREATE TABLE messages (
        id INT (7) NOT NULL auto_increment,
        USER VARCHAR (255) NOT NULL,
        msg text NOT NULL,
        time INT (9) NOT NULL,
        PRIMARY KEY (id)
    );

    HTML:

    <body>
    
        <div id="wrapper">
            <p id="messagewindow"><span id="loading">加载中...</span></p>
            <form id="chatform" action="#">
                姓名: <input type="text" id="author" size="50"/><br />
                内容: <input type="text" id="msg"  size="50"/>   <br /> 
                <input type="submit" value="发送" /><br />
            </form>
        </div>
    
    </body>

     书上给的例子只有PHP的....,你妹的我只懂JSP啊!!!结果只好自己用JSP来实现了。

    对于服务端:

    对于客户端:

    使用Myeclipse新建web工程,src目录下建servlet存放servlet类和数据操作的类。顺便说一句:引入jar包时,直接将jar包黏贴到web工程的lib目录下即可,不需要再build path了

    数据库操作,这里可以参照的是jdbc连接数据库的写法,以后直接拷贝:

     1 package servlets;
     2 
     3 import java.sql.Connection;
     4 import java.sql.DriverManager;
     5 
     6 public class DatabaseConnection {
     7     private static final String DBDRIVER = "org.gjt.mm.mysql.Driver";
     8     private static final String URL = "jdbc:mysql://localhost:3306/test";
     9     private static final String USER = "root";
    10     private static final String PASSWORD = "root";
    11     private Connection conn = null;
    12 
    13     public DatabaseConnection(){
    14         try{
    15             Class.forName(DBDRIVER);
    16             this.conn=DriverManager.getConnection(URL,USER,PASSWORD);
    17         }catch (Exception e) {
    18             e.printStackTrace();
    19         }
    20     }
    21     
    22     public Connection getConnection(){
    23         return conn;
    24     }
    25     
    26     public void close() throws Exception{
    27         if(conn!=null){
    28             try{
    29                 conn.close();
    30             }catch (Exception e) {
    31                 throw e;
    32             }
    33         }
    34     }
    35 }

    编写后端的servlet,用于处理前端页面发来的请求并将对应的请求结果发回给前端页面:

     1 package servlets;
     2 
     3 import java.io.IOException;
     4 import java.io.PrintWriter;
     5 import java.sql.Connection;
     6 import java.sql.PreparedStatement;
     7 import java.sql.ResultSet;
     8 import java.sql.SQLException;
     9 import java.text.SimpleDateFormat;
    10 import java.util.Date;
    11 
    12 import javax.servlet.ServletException;
    13 import javax.servlet.http.HttpServlet;
    14 import javax.servlet.http.HttpServletRequest;
    15 import javax.servlet.http.HttpServletResponse;
    16 
    17 public class AjaxServlet extends HttpServlet {
    18     DatabaseConnection db = new DatabaseConnection();
    19     Connection connection = db.getConnection();
    20     PreparedStatement pstmt = null;
    21 
    22     @Override
    23     protected void doGet(HttpServletRequest req, HttpServletResponse resp)
    24             throws ServletException, IOException {
    25         req.setCharacterEncoding("UTF-8"); 
    26         resp.setContentType("text/xml;charset=utf-8"); 
    27         resp.setHeader("Cache-Control", "no-cache");
    28         PrintWriter out = resp.getWriter(); //这里要注意
    29         int status_code = 2;
    30         String name = req.getParameter("name");
    31         String message = req.getParameter("message");
    32         String current=req.getParameter("time");
    33         Date d = new Date(); 
    34         SimpleDateFormat sdf = new SimpleDateFormat("MMddHHmmss");
    35         String dateNowStr = sdf.format(d);
    36         int time=Integer.parseInt(dateNowStr);
    37         if (req.getParameter("action") != null
    38                 && req.getParameter("action").equals("postmsg")) {
    39             String sql = "insert into messages (user, msg, time) values(?,?,?)";
    40             try {
    41                 pstmt = connection.prepareStatement(sql);
    42                 pstmt.setString(1, name);
    43                 pstmt.setString(2, message);
    44                 pstmt.setLong(3, time);
    45                 pstmt.execute();
    46             } catch (SQLException e) {
    47                 e.printStackTrace();
    48             }
    49         }
    50         String sql = "select user,msg from messages where time>? order by id asc";
    51         try {
    52             pstmt = connection.prepareStatement(sql);
    53             pstmt.setInt(1, Integer.parseInt(current));
    54             ResultSet resultSet = pstmt.executeQuery();
    55             if (resultSet.next()) {
    56                 status_code = 1;
    57             } else {
    58                 status_code = 2;
    59             }
    60             System.out.println(status_code);
    61             out.println("<?xml version='1.0' encoding='utf-8'?>");
    62             out.println("<response>");
    63             out.println("	<status>" + status_code + "</status>");
    64             out.println("	<time>" + time + "</time>");
    65             if (status_code == 1) {
    66                 do {
    67                     out.println("	<message>");
    68                     out.println("		<author>" + resultSet.getString("user")
    69                             + "</author>");
    70                     out.println("		<text>" + resultSet.getString("msg")
    71                             + "</text>");
    72                     out.println("	</message>");
    73                 } while (resultSet.next());
    74             }
    75             out.println("</response>");
    76         } catch (Exception e) {
    77             e.printStackTrace();
    78         }
    79     }
    80 
    81     @Override
    82     protected void doPost(HttpServletRequest req, HttpServletResponse resp)
    83             throws ServletException, IOException {
    84         // TODO Auto-generated method stub
    85         this.doGet(req, resp);
    86     }
    87 
    88 }

     自己写代码就会写得乱七八糟的.....,嘛、现在是完成主义就对了(并没有完成保持数据库中只有10条数据这个功能,懒)。上面代码的注意点有:

    1. 如何向前台页面返回XML文档?首先是

    resp.setContentType("text/xml;charset=utf-8");

    resp.setHeader("Cache-Control", "no-cache");

    设置了返回内容的类型,编码,头部。然后是 PrintWriter out = resp.getWriter(), 接着套xml的格式拼装打印输出到前端页面即可。

    2. 第二个要注意的比较基本,数据库基本API的使用:Connection  PreparedStatement  ResultSet之类的,jdbc的基本操作。

    3. 注意使用$.post(url,data,callback,type)时,JSP后端是怎么拿到data里的值的:req.getParameter("name")

    接下来在web.xml配置我们写的servlet:

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app version="2.5" 
        xmlns="http://java.sun.com/xml/ns/javaee" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
        http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
      <display-name></display-name>    
      <servlet>
          <servlet-name>ajax</servlet-name>
          <servlet-class>servlets.AjaxServlet</servlet-class>
      </servlet>
      <servlet-mapping>
          <servlet-name>ajax</servlet-name>
          <url-pattern>/back</url-pattern>
      </servlet-mapping>
      
    </web-app>

     编写脚本,下面是完整的前端页面:

     1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ TR/xhtml1/DTD/xhtml1-transitional.dtd">
     2 <html xmlns="http://www.w3.org/1999/xhtml">
     3 <head>
     4 <title></title>
     5 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
     6 <style>
     7 body {
     8     margin: 0;
     9     padding: 0;
    10     font-size: 12px;
    11 }
    12 
    13 #messagewindow {
    14     height: 250px;
    15     border: 1px solid;
    16     padding: 5px;
    17     overflow: auto;
    18 }
    19 
    20 #wrapper {
    21     margin: auto;
    22     width: 438px;
    23 }
    24 </style>
    25 <!--   引入jQuery -->
    26 <script src="scripts/jquery.js" type="text/javascript"></script>
    27 <script type="text/javascript">
    28     $(function(){
    29             //定义时间戳
    30             timestamp = 0;
    31             //调用更新信息函数
    32             updateMsg();
    33             //表单提交
    34             $("#chatform").submit(function(){
    35                 $.post("back",{
    36                             message: $("#msg").val(),
    37                             name: $("#author").val(),
    38                             action: "postmsg",
    39                             time: timestamp
    40                         }, function(xml) {
    41                     //清空信息文本框内容
    42                     $("#msg").val("");
    43                     //调用解析xml的函数
    44                     addMessages(xml);
    45                 });
    46                 return false; //阻止表单提交
    47             });
    48         });
    49         //更新信息函数,每隔一定时间去服务端读取数据
    50         function updateMsg(){
    51             $.post("back",{ time: timestamp }, function(xml) {
    52                 //移除掉 等待提示
    53                 $("#loading").remove();
    54                 //调用解析xml的函数
    55                 addMessages(xml);
    56             });
    57              //每隔4秒,读取一次.
    58             setTimeout('updateMsg()', 4000);
    59         }
    60         //解析xml文档函数,把数据显示到页面上
    61         function addMessages(xml) {
    62             //如果状态为2,则终止
    63             if($("status",xml).text() == "2") return;
    64             //更新时间戳
    65             timestamp = $("time",xml).text();
    66             //$.each循环数据
    67             $("message",xml).each(function() {
    68                 var author = $("author",this).text(); //发布者
    69                 var content = $("text",this).text();  //内容
    70                 var htmlcode = "<strong>"+author+"</strong>: "+content+"<br />";
    71                 $("#messagewindow").prepend( htmlcode ); //添加到文档中
    72             });
    73         }
    74 </script>
    75 </head>
    76 <body>
    77     <div id="wrapper">
    78         <p id="messagewindow">
    79             <span id="loading">加载中...</span>
    80         </p>
    81         <form id="chatform" action="#">
    82             姓名: <input type="text" id="author" size="50" /><br /> 内容: <input
    83                 type="text" id="msg" size="50" /> <br /> <input type="submit"
    84                 value="发送" /><br />
    85         </form>
    86     </div>
    87 </body>
    88 </html>

     上面的代码中要注意的是jQuery对xml文档的DOM操作:$("status",xml)方法用来通知jQuery去XML文档中寻找 "status"标签,找到后再利用text()方法取其标签里的文本即可。运行效果如下:

  • 相关阅读:
    七。进度管理
    六。质量管理
    五。项目范围管理
    四。项目整体管理
    三。项目立项管理
    二。项目的一般只知识
    一。项目管理的管理领域
    8.BGP
    英语词汇基础
    vim中输入tab符
  • 原文地址:https://www.cnblogs.com/f91og/p/6440384.html
Copyright © 2011-2022 走看看