AJAX?/span> JSON 发送请求数?/span>
Ø 使用XML 向服务器发送复杂的数据l构Q?/span>
Ø 通过串连接来创徏XML 串ƈ不好Q?/span>
Ø q也不是用来生成或修?/span>XML 数据l构的健壮技术?/span>
Ø JSQN 概述
* JSON ?/span> XML 的一个替代方法,可以?/span>www.Json.org 扑ֈ?/span> * JSON 是一U文本格式,它独立于具体语言Q?/span> * 使用了与C pd语言(?/span>C ?/span>C# ?/span>JavaScript {?/span>)cM的约定?/span> * JSON建立在以?/span> 两种数据l构基础上,当前几乎所有编E语a都支持这两种数据l构?/span> |
两种数据l构
Ø ?/span>/值对集合?/span>
* 不同的语a中,它被理解为对象(objectQ,U录 Q?/span>recordQ,l构Q?/span>structQ,字典Q?/span>dictionaryQ,哈希表(hash tableQ,有键列表Q?/span>keyed listQ,或者关联数l?/span> Q?/span>associative arrayQ?/span> |
Ø 值的有序表?/span>
* q通常实现Z个数l?/span> |
JSON的数据结?/span>
Ø JSON对象
* 对象是一个无序的“‘名称/?#8217;?#8221;集合。一个对象以“{”Q左括号Q开始,“}”Q右括号Q结束。每?#8220;名称”后跟一?#8220;:”Q冒PQ?#8220;‘名称/?#8217; ?#8221;之间使用“,”Q逗号Q分隔?/span> |
Ø JSON数组
* 数组是|valueQ的有序集合。一个数l以“[”Q左中括P开始,“]”Q右中括Pl束。g间?#8220;,”Q逗号Q分隔?/span> |
Ø ?/span>
* |valueQ可以是双引hh的字W串Q?/span>stringQ、数?/span>(number)?/span>true?/span>false?/span> null、对象(objectQ或者数l(arrayQ。这些结构可以嵌套?/span> |
Ø 字符ԌstringQ?/span>
* 字符ԌstringQ是由双引号包围的Q意数?/span>Unicode字符的集合,使用反斜U{义。一个字W(characterQ即一个单独的字符Ԍcharacter stringQ?/span> * 字符ԌstringQ与C或?/span>Java的字W串非常怼?/span> |
Ø 数|numberQ?/span>
* 数|numberQ也?/span>C或?/span>Java的数值非常相伹{除L曾用的八进制与十六q制格式。除M些编码细节?/span> |
Ø I白可以加入CQ何符号之间?/span> 以下描述了完整的语言?/span>
Ø ?/span>http://www.json.org/能得?/span>JSON?/span>
DEMO JSON对象
Ø 我们可以?/span>Employee对象的简单的例子展开q行?/span>
Ø Employee对象可能包含姓、名、员工号和职位等数据?/span>
Ø 使用JSONQ可以如下表C?/span>Employee对象实例Q?/span>
var employee = { “firstName”:”Zhou”, “lastName”:”DaQing”, “employeeNumber”:517, “title”:”Accountant” } |
Ø 然后可以使用标准点记法用对象的属性,如下所C:
n var lastName = employee.lastName;
n var title = employee.title;
n employee.employee = 517;
JSON?/span>XML
Ø JSON 是一个轻量的数据互换格式?/span>
Ø 如果?/span> XML 来描q同Lemployee对象Q可能如下所C:
<employee> <firstName>Zhou</firstName> <lastName>DaQing</lastName> <employeeNumbe>517</employeeNumbe> <title>Accountant</title> </employee > |
Ø 昄Q?/span>JSON~码?/span>XML ~码短?/span>
Ø 如果在网l上发送大量数据,可能会带来显著的性能差异?/span>
Ø www.Json.org |站列出了至与其他~程语言?/span>14U绑?/span> ?/span>
Ø q说明,不论在服务器端用何U技术,都能通过JSON与浏览器通信?/span>
JSON
Ø 因ؓq些l构得到了如此众多编E语a的支持,所?/span>JSON 可以作ؓ异构pȝ之间的一U数据互换格式?/span>
Ø 另外Q由?/span>JSON 是基于标?/span>JavaScript 的子集,所以在所有当?/span>Web 览器上都应该是兼容的?/span>
DEMO AJAX?/span> JSON 发送请求数?/span>
Ø DEMO
* 使用JSON ?/span>JavaScript 对象转换Z格式Q?/span> * Ajax 这个串发送到服务器, * 服务器根据这个串创徏一个对?/span>. |
Ø 撰写“jsonExample.html”Q如下:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>JSON Example</title> <script type="text/javascript" src="/js/json2.js"></script> <script type="text/javascript"> var xmlHttp; function createXMLHttpRequest() { if (window.ActiveXObject) { xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); } else if (window.XMLHttpRequest) { xmlHttp = new XMLHttpRequest(); } } function doJSON() { var car = getCarObject(); var carAsJSON = JSON.stringify(car); alert("Car object as JSON:"n" + carAsJSON); var url = "JSONExample?timeStamp=" + new Date().getTime(); createXMLHttpRequest(); xmlHttp.open("POST", url, true); xmlHttp.onreadystatechange = handleStateChange; xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); xmlHttp.send(carAsJSON); } function handleStateChange() { if (xmlHttp.readyState == 4) { if (xmlHttp.status == 200) { parseResults(); } } } function parseResults() { var responseDiv = document.getElementById("serverResponse"); if(responseDiv.hasChildNodes()) { responseDiv.removeChild(responseDiv.childNodes[0]); } var responseText = document.createTextNode(xmlHttp.responseText); responseDiv.appendChild(responseText); } function getCarObject() { return new Car("Dodge","Coronet R/T",1989,"pink"); } function Car(make, model, year, color) { this.make = make; this.model = model; this.year = year; this.color = color; } </script> </head> <body> <br/><br/> <form action="#"> <input type="button" value="Click here to send JSON data to the server" onblur="doJSON();"/> </form> <h2>Server Response:</h2> <div id="serverResponse"></div> </body> </html> |
DEMO 服务器端接收JSON数据
Ø 然后撰写“JSONExample.java”文gQ内容如下:
package org.yifeng.webapp.servlet; import org.json.JSONObject; import org.json.JSONException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.ServletException; import java.io.IOException; import java.io.BufferedReader; import java.text.ParseException; /** * Copyright: 晟YU技 * WebSit: http://www.shengruan.com * Author: 忆风 * QQ: 583305005 * MSN: YiFengs@msn.com * Email: zhdqCN@gmail.com * CreationTime: 2008-8-26 0:49:12 * Description: */ public class JSONExample extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String json = readJSONStringFromRequestBody(request); //q回输出l果 String responseText = null; //使用JSONl字Ajax对象 JSONObject jsonObject = null; try { jsonObject = new JSONObject(json); responseText = "You have a " + jsonObject.getInt("year") + " " + jsonObject.getString("make") + " " + jsonObject.getString("model") + " " + " that is " + jsonObject.getString("color") + " in color."; } catch (JSONException e) { e.printStackTrace(); } response.setContentType("text/xml"); response.getWriter().print(responseText); } private String readJSONStringFromRequestBody(HttpServletRequest request) { StringBuilder json = new StringBuilder(); String line = null; try { BufferedReader reader = request.getReader(); while ((line = reader.readLine()) != null) { json.append(line); } } catch (IOException e) { System.out.println("Error reading JSON stirng: " + e.toString()); } return json.toString(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } } |
Ø 点击按钮Q显C如下:
OK,看看Q数据都昄出来了吧Q呵呵!Q!
作者:周大庆(zhoudaqingQ?
|址Q?strong>http://m.tkk7.com/yifeng
>>>转蝲h明出处!<<<
发送请求参?/span>
Ø 目前我们已经讲了
1?nbsp;使用Ajax技术向服务器发送请?/span>
2?nbsp;也知道了可以采用多种Ҏ解析服务器的响应?/span>
Ø 只缺一个内容,是未将M数据作ؓh的一部分发送给服务器?/span>
GETҎ发送请求参?/span>
Ø GETҎQ作为名/值对攑֜hURL 中传递?/span>
* 资源URL 的问号后面就是名/值对?/span> * ?/span>/值对?/span> name=value 的Ş式, * 用与?/span>(&)分隔?/span> |
Ø 例如Q?/span>
http://localhost:8080/projectName?name=yifeng&password=hello |
POST Ҏ发送请求参?/span>
Ø POST ҎQ将参数串放在请求体中发送?/span>
* 参数~码为名/值对QŞ式ؓname=valueQ?/span> * 用与?/span>(&)分隔?/span> |
使用GET?/span>POST的徏?/span>
Ø 获取数据时应当?/span>GET Ҏ?/span>
* 数据处理不改变数据模型的状态?/span> |
Ø 存储、更新数据,使用POST Ҏ?/span>
* 操作改变了数据模型的状态?/span> |
Ø 特点?/span>
* GET h的参数编码到hURL 中,可以URL 建立书签。(不过Q如果是异步h没有什么用。) * GET h发送的数据量通常是固定的Q?/span>POST Ҏ可以发送Q意量的数据?/span> |
DEMO AJAX以名/值对发送请求参?/span>
Ø 使用GETh?/span>POSThQ创建查询字W串技术是一L?/span>
Ø 唯一的区别是Q?/span>GET发送请求时Q查询字W串q加到请?/span>URL中,
Ø POSTҎӞ?/span>XHR对象?/span>send()Ҏ时发送查询串?/span>
Ø DEMO
n getAndPostExample.html文g
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>Dynamically Editing Page Content</title> <script type="text/javascript" language="javascript"> var xmlHttp; function createXMLHttpRequest() { if (window.ActiveXObject) { xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); } else if (window.XMLHttpRequest) { xmlHttp = new XMLHttpRequest(); } } function createQueryString() { var firstName = document.getElementById("firstName").value; var middleName = document.getElementById("middleName").value; var birthday = document.getElementById("birthday").value; var queryString = "firstName=" + firstName + "&middleName=" + middleName + "&birthday=" + birthday;//?/span>/值对 return queryString; } function doRequestUsingGET() { createXMLHttpRequest(); var queryString = "GetAndPostExample?"; queryString = queryString + createQueryString() + "&timeStamp=" + new Date().getTime(); xmlHttp.onreadystatechange = handleStateChange; xmlHttp.open("GET", queryString, true); xmlHttp.send(null); } function doRequestUsingPOST() { createXMLHttpRequest(); var url = "GetAndPostExample?timeStamp=" + new Date().getTime(); //相同Ҏ生成?/span>/值对 var queryString = createQueryString(); xmlHttp.open("POST", url, true); xmlHttp.onreadystatechange = handleStateChange; xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); xmlHttp.send(queryString); } function handleStateChange() { if (xmlHttp.readyState == 4) { if (xmlHttp.status == 200) { parseResults(); } } } function parseResults() { var responseDiv = document.getElementById("serverResponse"); if (responseDiv.hasChildNodes()) { responseDiv.removeChild(responseDiv.childNodes[0]); } var responseText = document.createTextNode(xmlHttp.responseText); responseDiv.appendChild(responseText); } </script> </head> <body> <h1>Entery your first name, middle name, and birthday:</h1> <table> <tbody> <tr> <td>First name:</td> <td><input type="text" id="firstName"/></td> </tr> <tr> <td>Middle name:</td> <td><input type="text" id="middleName"></td> </tr> <tr> <td>Birthday:</td> <td><input type="text" id="birthday"/></td> </tr> </tbody> </table> <form action="#"> <input type="button" value="Send parameters using GET" onclick="doRequestUsingGET();"/> <br/><br/> <input type="button" value="Send parameters using POST" onclick="doRequestUsingPOST();"/> </form> <br/> <h2>Server Response:</h2> <div id="serverResponse"></div> </body> </html> |
n GetAndPostExample.java文g
package org.yifeng.webapp.servlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.ServletException; import java.io.IOException; import java.io.PrintWriter; /** * Copyright: 晟YU技 * WebSit: http://www.shengruan.com * Author: 忆风 * QQ: 583305005 * MSN: YiFengs@msn.com * Email: zhdqCN@gmail.com * CreationTime: 2008-8-25 22:44:44 * Description: */ public class GetAndPostExample extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/xml"); String firstName = request.getParameter("firstName"); String middleName = request.getParameter("middleName"); String birthday = request.getParameter("birthday"); StringBuilder responseText = new StringBuilder(); responseText.append("Hello, ").append(firstName).append(" " + middleName) .append(". Your birthday is " + birthday + ".") .append("[Method: " + request.getMethod() + "]"); PrintWriter out = response.getWriter(); out.println(responseText); out.flush(); out.close(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } } |
n Web.xml配置
<?xml version="1.0" encoding="UTF-8"?> <web-app 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" version="2.5"> <servlet> <servlet-name>GetAndPostExample</servlet-name> <servlet-class>org.yifeng.webapp.servlet.GetAndPostExample</servlet-class> </servlet> <servlet-mapping> <servlet-name>GetAndPostExample</servlet-name> <url-pattern>/GetAndPostExample</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>getAndPostExample.html</welcome-file> </welcome-file-list> </web-app> |
n 如果以点?#8220;Send parameters using GET”按钮Q如下图Q?br />
n 如果以点?#8220;Send parameters using POST”按钮Q如下图Q?br />
n 也许你会疑问Qؓ什么要?/span>URL后面q加旉呢?
* 有时览器会把多?/span>XMLHttpRequest h的结果缓存在同一?/span>URL. * 如果Ҏ个请求的响应不同Q这׃带来不好的结?/span>. * 把当前时间戳q加?/span> URL的最后,p保URL 的唯一性,从而避免浏览器~存l果. * IE有这U缓存问题,但是Firefox没有。你可以去试试,哈哈?/span> |
AJAX?/span> XML 发送请求数?/span>
Ø 只是使用一个包含名/值对的简单查询串Q这可能不够健壮Q?/span>
Ø 不以向服务器传递大量复杂的模型变化.
Ø 可以应用XML
Ø 如何向服务器发?/span>XML ?/span>?
Ø 可以?/span>XML 作ؓh体的一部分发送到服务器,
Ø q与POST h中将查询串作求体的一部分q行发送异曲同?/span>.
Ø 服务器可以从h体读?/span>XM LQƈ加以处理?/span>
Ø DEMO
Ø postingXML.html
DEMO AJAX?/span> XML 发送请求数?/span>
Ø 撰写“postingXML.html”文gQ如下:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>Sending and XML Request</title> <script type="text/javascript"> var xmlHttp; function createXMLHttpRequest() { if (window.ActiveXObject) { xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); } else if (window.XMLHttpRequest) { xmlHttp = new XMLHttpRequest(); } } /** * 生成XML */ function createXML() { var xml = "<pets>"; var options = document.getElementById("petTypes").childNodes; var option = null; for (var i = 0; i < options.length; i++) { option = options[i]; if (option.selected) { xml = xml + "<type>" + option.value + "<"/type>"; } } xml = xml + "<"/pets>"; return xml; } function sendPetTypes() { createXMLHttpRequest(); var xml = createXML(); var url = "PostingXMLExample?timeStamp=" + new Date().getTime(); xmlHttp.open("POST", url, true); xmlHttp.onreadystatechange = handleStateChange; xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); xmlHttp.send(xml); } function handleStateChange() { if (xmlHttp.readyState == 4) { if (xmlHttp.status == 200) { parseResults(); } } } function parseResults() { var responseDiv = document.getElementById("serverResponse"); if (responseDiv.hasChildNodes()) { responseDiv.removeChild(responseDiv.childNodes[0]); } var responseText = document.createTextNode(xmlHttp.responseText); responseDiv.appendChild(responseText); } </script> </head> <body> <h1>Select the types of pets in your home:</h1> <form action="#"> <select id="petTypes" size="6" multiple="true"> <option value="cats">Cats</option> <option value="dogs">Dogs</option> <option value="fish">Fish</option> <option value="birds">Birds</option> <option value="hamsters">Hamsters</option> <option value="rabbits">Rabbits</option> </select> <br/><br/> <input type="button" value="Submit Pets" onclick="sendPetTypes();"/> </form> <h2>Server Response:</h2> <div id="serverResponse"></div> </body> </html> |
Ø 撰写“PostingXMLExample.java”文gQ如下:
package org.yifeng.webapp.servlet; import org.w3c.dom.Document; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.ServletException; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import java.io.IOException; import java.io.BufferedReader; import java.io.ByteArrayInputStream; /** * Copyright: 晟YU技 * WebSit: http://www.shengruan.com * Author: 忆风 * QQ: 583305005 * MSN: YiFengs@msn.com * Email: zhdqCN@gmail.com * CreationTime: 2008-8-25 23:30:41 * Description: */ public class PostingXMLExample extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String xml = readXMLFromRequestBody(request);//获得XML字符?/span> Document xmlDoc = null; try { xmlDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new ByteArrayInputStream(xml.getBytes())); } catch (SAXException e) { System.out.println("SAXException: " + e); } catch (ParserConfigurationException e) { System.out.println("ParserConfigurationException: " + e); } /** * Java?/span>JavaScript均有W3C DOM的实玎ͼ比如getElementByTagName?/span>getNodeValueҎ */ NodeList selectedPetTypes = xmlDoc.getElementsByTagName("type"); String type = null; String responseText = "Selected Pets: "; for (int i = 0; i < selectedPetTypes.getLength(); i++) { type = selectedPetTypes.item(i).getFirstChild().getNodeValue(); responseText = responseText + " " + type; } response.setContentType("text/xml"); response.getWriter().print(responseText); } private String readXMLFromRequestBody(HttpServletRequest request) { StringBuilder xml = new StringBuilder(); String line = null; try { BufferedReader reader = request.getReader(); while ((line = reader.readLine()) != null) { xml.append(line); } } catch (Exception e) { System.out.println("Error reading XML: " + e.toString()); } return xml.toString(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } } |
Ø q行Q显C如下:
作者:周大庆(zhoudaqingQ?
|址Q?strong>http://m.tkk7.com/yifeng
>>>转蝲h明出处!<<<
创徏XHR发送请?/span>
Ø 如下Q?/span>
<script type="text/javascript"> var xmlHttp; //创徏一?/span>XMLHttpRequest对象 function createXMLHttpRequest() { // For Internet Explorer 5.5, 6, 7 if (window.ActiveXObject) { xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); } // For Mozilla, Firefox, Safari, Netscape else if (window.XMLHttpRequest) { xmlHttp = new XMLHttpRequest(); } } </script> |
AJAX发送请?/span>
Ø 如下Q?/span>
function startRequest() { createXMLHttpRequest(); //注册回调事g处理器 xmlHttp.onreadystatechange = handleStateChange; //使用Open()Ҏ初始?/span>XMLHttpRequest对象-指定HTTPҎ //和要使用的服务器URL xmlHttp.open("GET", "innerHTML.xml", true); //send()Ҏ发送该h xmlHttp.send(null); } |
应用GET POST发送请?/span>
Ø Ҏ如下Q?/span>
Ҏ?/span> |
描述 |
getElementById(id) (document) |
获取有指定唯一ID属性值文档中的元?/span> |
getElementsByTagName(name) |
q回当前元素中有指定标记名的子元素的数组 |
hasChildNodes() |
q回一个布|指示元素是否有子元素 |
getAttribute(name) |
q回元素的属性|属性由name指定 |
处理服务器晌?/span>
XMLHttpRequest 提供了两个可以用来访问服务器响应的属?/span>.
Ø responseText Q将响应提供Z个串?/span>
Ø responseXMLQ将响应提供Z?/span>XML 对象?/span>
使用innerHTML 属性创建动态内?/span>
Ø responseText Q innerHtmlQ?/span>
服务器 "生"或生?/span>HTML 内容Q?/span>
览器用 innerHTML?/span>"消费"或处理?/span>
DEMO responseText Q innerHtml
Ø innerHTM.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Using responseText with innerHTML</title> <META http-equiv=Content-Type content="text/html; charset=GBK"> <script type="text/javascript"> var xmlHttp; function createXMLHttpRequest() { if (window.ActiveXObject) { xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); } else if (window.XMLHttpRequest) { xmlHttp = new XMLHttpRequest(); } } function startRequest() { createXMLHttpRequest(); xmlHttp.onreadystatechange = handleStateChange; xmlHttp.open("GET", "innerHTML.txt", true); xmlHttp.send(null); } function handleStateChange() { if(xmlHttp.readyState == 4) { if(xmlHttp.status == 200) { document.getElementById("results").innerHTML = xmlHttp.responseText; } } } </script> </head> <body> <form action="#"> please content:<input type="button" value="Search for Today’s Activities" onclick="startRequest();" /> <span id="results"></span> </form> </body> </html> |
Ø innerHTML.txt
误入内容!Q! |
Ø 输出l果Q?/span>
AJAX历史
Ø 2005q?/span>2?/span>, Adaptive Path ?/span>Jesse James Garrett 最早创造了q个词?/span>
Ø Ajax:A New Approach to Web Applications (Ajax: Web 应用的一U新Ҏ)中,Garrett讨论?/span> 如何消除胖客?/span>(或桌?/span>)应用与瘦客户(?/span>Web) 应用之间的界?/span>.
Ø 以前认ؓ是 "Asynchronous JavaScript + XML" 的羃?/span>.
Ø 目前认ؓ?/span>:允许览器与服务器通信而无需h当前面的技?/span>.
Ø Famous examples : Google Maps , Google Suggest , GMail ,Outlook Web Access
Ø New bottle of old wine
Ø The next generation browser will have built-in UI Component(XUL etc),IE7?/span>XMLHttpRequest实现Z个窗口对象属?/span>.
什么是AJAX
Ø AJAX技术是Asynchronous JavaScript XML(异步JavaScript ?/span>XML)的简UͼAjax提供与服务器异步通信的能力,一个无需h整个面而在|页中更C部分数据的应用。
AJAX是一门新技术?
Ø AJAX不是一个新技术。它包含Q?/span>
1. Z标准的展CZ用 XHTML?/span>CSS;
2. 动态显C和交互使用 文对象模型DOM;
3. 数据交换和操U用 XML?/span>XSLT?/span>JSON;
4. 异步数据索方法?/span> XMLHttpRequest(XHR);
5. _胶剂?/span> JavaScript?/span>
Web 1.0 & Web 2.0
Ø Web 1.0 – 同步(Synchronous)
Ø Web 2.0 非同?/span>(Asynchronous)
AJAX原理?/span>
此文以实例ؓ基础一步步说明了jQuery的工作方式。现以中文翻译(d我的补充说明Q如下。如有相x见或请麻烦到我的 BLOG 写个回复或?EMAIL 告知?/p>
英文原版Q?a >http://jquery.bassistance.de/jquery-getting-started.html Q感谢原文作?Jörn Zaefferer
本文发布已征求原作者同意?/strong>
另外我认为在学习q程?有两个API文档你要打开随时查看:
q个指南是一个对jQuery库的说明Q要求读者了解HTML(DOM)和CSS的一些常识。它包括了一个简单的Hello World的例子,选择器和事g基础QAJAX、FX的用法,以及如何制作jQuery的插件?q个指南包括了很多代码,你可以copy它们Qƈ试着修改它们Q看看生的效果?
一开?我们需要一个jQuery的库,最新的下蝲可以?a >q里扑ֈ。这个指南提供一个基本包含实例的包供下蝲.
下蝲Q?a class="download" >jQuery Starterkit
(译者Keel?一定要下蝲q个包,光看文章不实践肯定是不行的?
下蝲后解压羃Q然后用你最喜欢的文本编辑器打开starterkit.html和custom.jsq两个文件?span class="log">(译者Keel?q两个就是例子文?所有的例子都用q两个例子作?custom.js写jQuery代码,starterkit.html观察效果.用editPlus打开)
现在,我们已l做好了一切准备来q行q个著名?Hello world"例子.
在做所有事情之?我们要让jQueryd和处理文的DOM,必须可能快地在DOM载入后开始执行事?所?我们用一个ready事g作ؓ处理HTML文的开?看看我们打开的custom.jsq个文g,里面已经准备好了:
$(document).ready(function() {
// do stuff when DOM is ready
});
放一个简单的alert事g在需要等DOM完成载入,所以我们把dE稍变复杂一?在点MQ何一个链接时昄一个alert.
$(document).ready(function() {
$("a").click(function() {
alert("Hello world!");
});
});
q样在你点击面的一个链接时都会触发q个"Hello world"的提C?/p>
(译者Keel?L此代码修改custom.jsq保?然后用浏览器打开starterkit.html观察效果?
让我们看一下这些修Ҏ什么含义?("a") 是一个jQuery选择?selector),在这里,它选择所有的a标签Q译者Keel注:?lt;a></a>Q?/span>Q? h jQuery “c?#8221;(jQuery "class")的一个别Uͼ因此$()构造了一个新的jQuery 对象(jQuery object)。函?click() 是这个jQuery对象的一个方法,它绑定了一个单M件到所有选中的标{?q里是所有的a标签),q在事g触发时执行了它所提供的alertҎ.
q里有一个拟行相似功能的代码:
<a href="#" onclick="alert('Hello world')">Link</a>
不同之处很明?用jQuery不需要在每个a标签上写onclick事g,所以我们拥有了一个整z的l构文(HTML)和一个行为文?JS),辑ֈ了将l构与行为分开的目?像我们使用CSSq求的一?
下面我们会更多地了解到选择器与事g.
jQuery提供两种方式来选择html?elementsQ第一U是用CSS和Xpath选择器联合v来Ş成一个字W串来传送到jQuery的构造器Q如Q?("div > ul a")Q;W二U是用jQuery对象的几个methods(Ҏ)。这两种方式q可以联合v来合用?/p>
Z试一下这些选择器,我们来试着在我们starterkit.html中选择q修改第一个ordered list.
一开始,我们需要选择q个list本nQ这个list有一个ID?#8220;orderedlist”Q通常的javascript写法是document.getElementById("orderedlist").在jQuery中,我们q样做:
$(document).ready(function() {
$("#orderedlist").addClass("red");
});
q里starterkit中的一个CSS样式red附加Corderedlist?span class="log">(译者Keel注:参考测试包中的css目录下的core.cssQ其中定义了red样式)。因此,在你h了starterkit.html后,你将会看到第一个有序列?ordered list )背景色变成了U色Q而第二个有序列表没有变化.
现在Q让我们d一些新的样式到list的子节点.
$(document).ready(function() {
$("#orderedlist > li").addClass("blue");
});
q样Q所有orderedlist中的li都附加了样式"blue"?/p>
现在我们再做个复杂一点的Q当把鼠标放在li对象上面和移开时进行样式切换,但只在list的最后一个element上生效?/p>
$(document).ready(function() {
$("#orderedlist li:last").hover(function() {
$(this).addClass("green");
}, function() {
$(this).removeClass("green");
});
});
q有大量的类似的CSS?a class="doc" title="Documentation for XPath selectors" >XPath例子Q更多的例子和列表可以在q里扑ֈ?span class="log">Q译者Keel注:入门看此文,修行在个人,要想在入门之后懂更多Q所以这D话的几个链接迟早是要必看的Q不会又要翻译吧...^_^!Q?/span>
每一个onXXX事g都有效,如onclick,onchange,onsubmit{,都有jQuery{h表示ҎQ译者Keel注:jQuery不喜ƢonXXXQ所以都Ҏ了XXXQ去掉了onQ?/span>?a class="doc" title="Documentation for advanced events" >其他的一些事?/a>Q如ready和hover,也提供了相应的方法?/p>
你可以在Visual jQuery扑ֈ全部的事件列表,在Events栏目? 用这些选择器和事g你已l可以做很多的事情了Q但q里有一个更强的好东东! find() 让你在已l选择的element中作条g查找,因此 $("#orderedlist).find("li") 像 $("#orderedlist li"). each()一栯P代了所有的liQƈ可以在此基础上作更多的处理?大部分的Ҏ,如addClass(), 都可以用它们自己?each() 。在q个例子? html()用来获取每个li的html文本, q加一些文字,q将之设|ؓli的html文本?span class="log">Q译者Keel注:从这个例子可以看?html()Ҏ是获取对象的html代码Q?html('xxx')是设|?xxx'为对象的html代码Q?/span> 另一个经常碰到的d是在没有被jQuery覆盖的DOM元素上call一些方法,惛_一个在你用AJAX方式成功提交后的resetQ?/p>
Q译者Keel注:q里作者将form的id也写成了formQ源文g?lt;form id="form">Q这是非怸好的写法Q你可以这个IDҎform1或者testFormQ然后用$("#form1")或? ("#testForm")来表C它Q再q行试。) q个代码选择了所有ID?form"的元素,q在其第一个上call了一个reset()。如果你有一个以上的formQ你可以q样做: Q译者Keel注:h意一定要亲自这些代码写在custom.js中ƈ在starterkit.html上测试效果才能有所体会Q必要时要观察starterkit.html的html代码Q?/p>
q样你在点击Reset链接后,选择了文中所有的form元素Qƈ对它们都执行了一ơreset()?/p>
q?有一个你可能要面对的问题是不希望某些特定的元素被选择。jQuery 提供了filter() 和not() Ҏ来解册个问题?filter()以过滤表辑ּ来减不W合的被选择? not()则用来取消所有符合过滤表辑ּ的被选择? 考虑一个无序的listQ你惌选择所有的没有ul子元素的li元素?/p>
q个代码选择了所有的li元素Q然后去除了没有ul子元素的li元素。刷新浏览器后,所有的li元素都有了一个边框,只有ul子元素的那个li元素例外?/p>
Q译 者Keel注:h意体会方便之极的css()ҎQƈ再次提醒请务必实际测试观察效果,比方说换个CSS样式呢?再加一个CSS样式呢?像这P$ ("li").not("[ul]").css("border", "1px solid black").css("color","red");Q?/p>
上面代码中的[expression] 语法是从XPath而来Q可以在子元素和属?elements and attributes)上用作过滤器Q比如你可能想选择所有的带有name属性的链接: q个代码l所有带有name属性的链接加了一个背景色?span class="log">Q译者Keel注:q个颜色太不明显了,写成$("a[@name]").background("red");Q?/span> 更常见的情况是以name来选择链接Q你可能需要选择一个有特点href属性的链接Q这在不同的览器下对href的理解可能会不一_所以我们的部分匚w("*=")的方式来代替完全匚w("=")Q?/p>
到现在ؓ止,选择器都用来选择子元素或者是qo元素。另外还有一U情冉|选择上一个或者下一个元素,比如一个FAQ的页面,{案首先会隐藏,当问题点LQ答案显C出来,jQuery代码如下Q?/p>
q?里我们用了一些链式表达法来减代码量Q而且看上L直观更容易理解。像'#faq' 只选择了一ơ,利用end()ҎQ第一ơfind()Ҏ会结?undone)Q所以我们可以接着在后面lfind('dt')Q而不需要再? ('#faq').find('dt')?/p>
在点M件中的,我们?$(this).next() 来找到dt下面紧接的一个dd元素Q这让我们可以快速地选择在被点击问题下面的答案?/p>
Q译 者Keel注:q个例子真是太酷了,FAQ中的{案可以收羃Q从利用next()的思\到实现这些效果都有很多地斚w要我们消化,注意 if (answer.is(':visible'))用法Q注意answer.slideUp();不懂的地方赶紧查我在最开始提到的两个必看API文档Q?/p>
除了选择同别的元素外,你也可以选择父的元素。可能你惛_用户鼠标Ud文章某段的某个链接时Q它的父U元?-也就是文章的q一D늪出显C,试试q个Q?/p>
试效果可以看到Q移到文章某D늚链接Ӟ它所在的D全用上highlight样式Q移C后又恢复原样?/p>
Q译者Keel注:highlight是core.css中定义的样式Q你也可以改变它Q注意这里有W二个function()q是hoverҎ的特点,请在API文中查阅hoverQ上面也有例子说明)
在我们l之前我们先来看看这一步: jQuery会让代码变得更短从而更Ҏ理解和维护,下面?(document).ready(callback)的羃写法Q?/p>
应用到我们的Hello world例子中,可以q样: 现在Q我们手上有了这些基的知识,我们可以更进一步的探烦其它斚w的东西,׃AJAX开始!$(document).ready(function() {
$("#orderedlist").find("li").each(function(i) {
$(this).html( $(this).html() + " BAM! " + i );
});
});$(document).ready(function() {
// use this to reset a single form
$("#reset").click(function() {
$("#form")[0].reset();
});
});$(document).ready(function() {
// use this to reset several forms at once
$("#reset").click(function() {
$("form").each(function() {
this.reset();
});
});
});$(document).ready(function() {
$("li").not("[ul]").css("border", "1px solid black");
});$(document).ready(function() {
$("a[@name]").background("#eee");
});$(document).ready(function() {
$("a[@href*=/content/gallery]").click(function() {
// do something with all links that point somewhere to /content/gallery
});
});$(document).ready(function() {
$('#faq').find('dd').hide().end().find('dt').click(function() {
var answer = $(this).next();
if (answer.is(':visible')) {
answer.slideUp();
} else {
answer.slideDown();
}
});
});$(document).ready(function() {
$("a").hover(function() {
$(this).parents("p").addClass("highlight");
}, function() {
$(this).parents("p").removeClass("highlight");
});
});$(function() {
// code to execute when the DOM is ready
});$(function() {
$("a").click(function() {
alert("Hello world!");
});
});本章的相关链?
在这一部分我们写了一个小的AJAX应用Q它能够rate一些东?span class="log">Q译Keel注:是Ҏ些东西投)Q就像在youtube.com上面看到的一栗?/p>
首先我们需要一些服务器端代码,q个例子中用C一个PHP文gQ读取rating参数然后q回ratingL和^均数。看一?a >rate.php代码.
虽然q些例子也可以不使用AJAX来实玎ͼ但显C我们不会那么做Q我们用jQuery生成一个DIV容器QID?rating".
$(document).ready(function() {
// generate markup
var ratingMarkup = ["Please rate: "];
for(var i=1; i <= 5; i++) {
ratingMarkup[ratingMarkup.length] = "<a href='#'>" + i + "</a> ";
}
// add markup to container and applier click handlers to anchors
$("#rating").append( ratingMarkup.join('') ).find("a").click(function(e) {
e.preventDefault();
// send requests
$.post("rate.php", {rating: $(this).html()}, function(xml) {
// format result
var result = [
"Thanks for rating, current average: ",
$("average", xml).text(),
", number of votes: ",
$("count", xml).text()
];
// output result
$("#rating").html(result.join(''));
} );
});
});
q段代码生成?个链接,q将它们q加到id?rating"容器中,当其中一个链接被点击Ӟ该链接标明的分数׃以rating参数形式发送到rate.phpQ然后,l果以XML形式会从服务器端传回来,d到容器中Q替代这些链接?/p>
如果你没有一个安装过PHP的webserverQ你可以看看q个在线的例?/a>.
不用javascript实现的例子可以访?softonic.de 点击 "Kurz bewerten!"
更多的AJAXҎ可以?a class="doc" title="Documentation for AJAX methods" >q里 扑ֈQ或者看?a >API文档 下面的AJAX filed under AJAX.
Q译者Keel注:q个在线实例从国内访问还是比较慢的,点击后要{一会儿才能看到l果Q可以考虑对它q行修改Q比如加上loadingQ投后加上再投的q回链接{。此外,q个例子中还是有很多需要进一步消化的地方Q看不懂的地方请参考API文。)
一个在使用AJAX载入内容时经常发生的问题是:当蝲入一个事件句柄到一个HTML文档Ӟq需要在载入内容上应用这些事Ӟ你不得不在内容加载完成后应用q些事g句柄Qؓ了防止代码重复执行,你可能用到如下一个function:
// lets use the shortcut
$(function() {
var addClickHandlers = function() {
$("a.clickMeToLoadContent").click(function() {
$("#target").load(this.href, addClickHandlers);
});
};
addClickHandlers();
});
现在QaddClickHandlers只在DOM载入完成后执行一ơ,q是在用hơ点d有clickMeToLoadContent q个样式的链接ƈ且内容加载完成后.
h意addClickHandlers函数是作Z个局部变量定义的Q而不是全局变量(如:function addClickHandlers() {...})Q这样做是ؓ了防止与其他的全局变量或者函数相冲突.
另一个常见的问题是关于回?callback)的参数。你可以通过一个额外的参数指定回调的方法,单的办法是将q个回调Ҏ包含在一个其它的function?
// get some data
var foobar = ...;
// specify handler, it needs data as a paramter
var handler = function(data) {
...
};
// add click handler and pass foobar!
$('a').click( function(event) { handler(foobar); } );
// if you need the context of the original handler, use apply:
$('a').click( function(event) { handler.apply(this, [foobar]); } );
用到单的AJAX后,我们可以认ؓ已经非常?#8220;web2.0”了,但是到现在ؓ止,我们q缺一些酷炫的效果。下一节将会谈到这些效?
一些动态的效果可以使用 show()
?hide()
来表?
$(document).ready(function() {
$("a").toggle(function() {
$(".stuff").hide('slow');
}, function() {
$(".stuff").show('fast');
});
});
你可以与 animate()
联合h创徏一些效?如一个带渐显的滑动效?
$(document).ready(function() {
$("a").toggle(function() {
$(".stuff").animate({
height: 'hide',
opacity: 'hide'
}, 'slow');
}, function() {
$(".stuff").animate({
height: 'show',
opacity: 'show'
}, 'slow');
});
});
很多不错的效果可以访?a >interface plugin collection. q个站点提供了很多demos和文?/p>
q些效果插g是位于jQuery插g列表的前面的Q当然也有很多其他的插gQ比如我们下一章讲到的表格排序插g?/p>
q个表格排序插g能让我们在客L按某一列进行排序,引入jQuery和这个插件的js文gQ然后告诉插件你惌哪个表格拥有排序功能?/p>
要测试这个例子,先在starterkit.html中加上像下面q一行的代码Q?/p>
<script src="lib/jquery.tablesorter.js" type="text/javascript"></script>
然后可以q样调用不着:
$(document).ready(function() {
$("#large").tableSorter();
});
现在点击表格的第一行head区域Q你可以看到排序的效果,再次点击会按倒过来的序q行排列?/p>
q个表格q可以加一些突出显C的效果Q我们可以做q样一个隔行背景色Q斑马线Q效?
$(document).ready(function() {
$("#large").tableSorter({
stripingRowClass: ['odd','even'], // Class names for striping supplyed as a array.
stripRowsOnStartUp: true // Strip rows on tableSorter init.
});
});
关于q个插g的更多例子和文可以?tablesorter首页扑ֈ.
几乎所有的特g都是q样用的:先include插g的js文g,然后在某些元素上使用插g定义的方?当然也有一些参数选项是可以配|的
l常更新的插件列表可以从jQuery官方?on the jQuery site扑ֈ.
当你更经常地使用jQuery?你会发现你自己的代码打包成插g是很有用处的,它能方便地让你的公司或者其他hq行重用.下一章我们将谈到如何构徏一个自q插g.
写一个自qjQuery插g是非常容易的,如果你按照下面的原则来做,可以让其他h也容易地l合使用你的插g.
jQuery.fn.foobar = function() {
// do something
};
jQuery.fooBar = {
height: 5,
calculateBar = function() { ... },
checkDependencies = function() { ... }
};
你现在可以在你的插g中用这些帮助函C:
jQuery.fn.foobar = function() {
// do something
jQuery.foobar.checkDependencies(value);
// do something else
};
jQuery.fn.foobar = function(options) {
var settings = {
value: 5,
name: "pete",
bar: 655
};
if(options) {
jQuery.extend(settings, options);
}
};
现在可以无需做Q何配|地使用插g?默认的参数在此时生效:
$("...").foobar();
或者加入这些参数定?
$("...").foobar({
value: 123,
bar: 9
});
如果你release你的插g, 你还应该提供一些例子和文档,大部分的插g都具备这些良好的参考文?
现在你应该有了写一个插件的基础,让我们试着用这些知识写一个自q插g.
很多着控制所有的radio或者checkbox是否被选中,比如:
$("input[@type='checkbox']").each(function() {
this.checked = true;
// or, to uncheck
this.checked = false;
// or, to toggle
this.checked = !this.checked;
});
无论何时候,当你的代码出现eachӞ你应该重写上面的代码来构造一个插?很直接地:
$.fn.check = function() {
return this.each(function() {
this.checked = true;
});
};
q个插g现在可以q样?
$("input[@type='checkbox']").check();
现在你应该还可以写出uncheck()和toggleCheck()?但是先停一?让我们的插g接收一些参?
$.fn.check = function(mode) {
var mode = mode || 'on'; // if mode is undefined, use 'on' as default
return this.each(function() {
switch(mode) {
case 'on':
this.checked = true;
break;
case 'off':
this.checked = false;
break;
case 'toggle':
this.checked = !this.checked;
break;
}
});
};
q里我们讄了默认的参数,所以将"on"参数省略也是可以?当然也可以加?on","off", ?"toggle",?
$("input[@type='checkbox']").check();
$("input[@type='checkbox']").check('on');
$("input[@type='checkbox']").check('off');
$("input[@type='checkbox']").check('toggle');
如果有多于一个的参数讄会稍E有点复?在用时如果只想讄W二个参?则要在第一个参C|写入null.
从上一章的tablesorter插g用法我们可以看到,既可以省略所有参数来使用或者通过一?key/value Ҏ重新讄每个参数.
作ؓ一个练?你可以试着?W四?/a> 的功能重写ؓ一个插?q个插g的骨架应该是像这L:
$.fn.rateMe = function(options) {
var container = this; // instead of selecting a static container with $("#rating"), we now use the jQuery context
var settings = {
url: "rate.php"
// put more defaults here
// remember to put a comma (",") after each pair, but not after the last one!
};
if(options) { // check if options are present before extending the settings
$.extend(settings, options);
}
// ...
// rest of the code
// ...
return this; // if possible, return "this" to not break the chain
});
如果你想做更好的javascript开?你用一个叫 FireBug的firefox插g. 它提供了断点调试(比alert强多?、观察DOM变化{很多漂亮的功能
如果你还有未解决的问题,或者新的想法与Q你可以使用jQuery的邮件列?jQuery mailing list.
关于q个指南的Q何事情,你可以写maill作者或者发表评论在他的日志Q?a >blog.
关于q个指南的翻译Q何事情,你可以写maill我或者发表评论在我的日志Q?a >blog.
大大感谢John Resig创造了q么好的library! 感谢jQuery community 为John提供了如此多的咖啡和其他的一?