詳解js的延遲對象、跨域、模板引擎、彈出層、AJAX【附實(shí)例下載】
目錄
一、AJAX示例
1.1、優(yōu)點(diǎn)
1.2、缺點(diǎn)
1.3、jQuery AJAX示例
二、延遲對象(Deferred)
2.1、回調(diào)函數(shù)
2.2、deferred.done
三、跨域
3.1、什么是跨域
3.2、JSONP跨域
3.3、jQuery使用JSONP跨域
3.4、跨域資源共享(CORS)
3.5、小結(jié)
四、彈出層
五、模板引擎
- 5.1、Hello World
- 5.2、方法
- 5.3、與AJAX結(jié)合應(yīng)用
六、示例下載
一、AJAX示例
AJAX全稱為“Asynchronous JavaScript And XML”(異步JavaScript和XML) 是指一種創(chuàng)建交互式網(wǎng)頁應(yīng)用的開發(fā)技術(shù)、改善用戶體驗(yàn),實(shí)現(xiàn)無刷新效果。
1.1、優(yōu)點(diǎn)
不需要插件支持
優(yōu)秀的用戶體驗(yàn)
提高Web程序的性能
減輕服務(wù)器和帶寬的負(fù)擔(dān)
1.2、缺點(diǎn)
瀏覽器對XMLHttpRequest對象的支持度不足,幾乎所有瀏覽器現(xiàn)在都支持
破壞瀏覽器“前進(jìn)”、“后退”按鈕的正常功能,可以通過簡單的插件彌補(bǔ)
對搜索引擎的支持不足
1.3、jQuery AJAX示例
在HTML5中對原生的AJAX核心對象XMLHttpRequest進(jìn)行升級,也就是XHR2,功能更加強(qiáng)大。
jQuery對AJAX封裝的非常好,這里以簡單的商品管理為示例使用jQuery完成AJAX應(yīng)用。
Product.java bean:
package com.gomall.bean; /*** * 產(chǎn)品 * * @author Administrator * */ public class Product { /** 編號 */ private int id; /** 名稱 */ private String name; /** 價(jià)格 */ private double price; /** 圖片 */ private String picture; /** 詳細(xì) */ private String detail; @Override public String toString() { return "Product [id=" + id + ", name=" + name + ", price=" + price + ", picture=" + picture + ", detail=" + detail + "]"; } public Product(int id, String name, double price, String picture) { super(); this.id = id; this.name = name; this.price = price; this.picture = picture; } public Product(int id, String name, double price, String picture, String detail) { super(); this.id = id; this.name = name; this.price = price; this.picture = picture; this.detail = detail; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } public String getPicture() { return picture; } public void setPicture(String picture) { this.picture = picture; } public String getDetail() { return detail; } public void setDetail(String detail) { this.detail = detail; } }
IProductService.java:
package com.gomall.service; import java.util.List; import com.gomall.bean.Product; public interface IProductService { /**獲得所有*/ List<Product> getAll(); /**添加 * @return */ boolean add(Product entity); /**根據(jù)編號獲得產(chǎn)品對象*/ Product findById(int id); /**根據(jù)編號獲得產(chǎn)品對象 * @return */ boolean deleteById(int id); }
ProductService.java:
package com.gomall.service; import java.util.ArrayList; import java.util.List; import java.util.Random; import com.gomall.bean.Product; public class ProductService implements IProductService { public static ArrayList<Product> products; static { products = new ArrayList<>(); Random random = new Random(); for (int i = 1; i <= 10; i++) { Product product = new Product(i, "華為Mate9MHA-AL00/4GB RAM/全網(wǎng)通華為超級閃充技術(shù)雙后攝設(shè)計(jì)" + random.nextInt(999), random.nextDouble() * 1000, "pic(" + i + ").jpg", "產(chǎn)品詳細(xì)"); products.add(product); } } /* * (non-Javadoc) * * @see com.gomall.service.IProductService#getAll() */ @Override public List<Product> getAll() { return products; } /* * (non-Javadoc) * * @see com.gomall.service.IProductService#add(com.gomall.bean.Product) */ @Override public boolean add(Product entity) { try { entity.setId(products.size() + 1); entity.setPicture("pic(" + entity.getId() + ").jpg"); // uploadify // 上傳圖片 products.add(entity); } catch (Exception e) { e.printStackTrace(); return false; } return true; } /* * (non-Javadoc) * * @see com.gomall.service.IProductService#findById(int) */ @Override public Product findById(int id) { for (Product product : products) { if (product.getId() == id) { return product; } } return null; } /* * (non-Javadoc) * * @see com.gomall.service.IProductService#deleteById(int) */ @Override public boolean deleteById(int id) { try { Product product = findById(id); if (product != null) { products.remove(product); } } catch (Exception e) { e.printStackTrace(); return false; } return true; } }
ProductAction.java:
package com.gomall.action; import java.io.IOException; import java.io.PrintWriter; import java.util.Date; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.codehaus.jackson.map.ObjectMapper; import com.gomall.bean.Product; import com.gomall.service.IProductService; import com.gomall.service.ProductService; @WebServlet("/Product") public class ProductAction extends HttpServlet { private static final long serialVersionUID = 1L; public ProductAction() { super(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { /*模擬網(wǎng)絡(luò)延時(shí)*/ try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } request.setCharacterEncoding("utf-8"); response.setCharacterEncoding("utf-8"); String act = request.getParameter("act"); IProductService productService = new ProductService(); /**用于序列化json*/ ObjectMapper mapper = new ObjectMapper(); PrintWriter out=response.getWriter(); if (act.equals("getAll")) { String json = mapper.writeValueAsString(productService.getAll()); out.append(json); } else if (act.equals("area")) { String callback=request.getParameter("callback"); out.append(callback+"('"+new Date()+"')"); } else if (act.equals("getJSONP")) { String callback=request.getParameter("callback"); String json = mapper.writeValueAsString(productService.getAll()); out.append(callback+"("+json+")"); } else if (act.equals("getAllCORS")) { /**向響應(yīng)的頭部中添加CORS信息*/ response.addHeader("Access-Control-Allow-Origin", "*"); response.addHeader("Access-Control-Allow-Methods", "GET,POST"); String json = mapper.writeValueAsString(productService.getAll()); out.append(json); } else if(act.equals("del")){ /**向響應(yīng)的頭部中添加CORS信息*/ response.addHeader("Access-Control-Allow-Origin", "*"); response.addHeader("Access-Control-Allow-Methods", "GET,POST"); int id=Integer.parseInt(request.getParameter("id")); String json = mapper.writeValueAsString(productService.deleteById(id)); out.append(json); } else if(act.equals("add")){ /**向響應(yīng)的頭部中添加CORS信息*/ response.addHeader("Access-Control-Allow-Origin", "*"); response.addHeader("Access-Control-Allow-Methods", "GET,POST"); String name=request.getParameter("name"); double price=Double.parseDouble(request.getParameter("price")); String detail=request.getParameter("detail"); Product entity=new Product(0, name, price, "",detail); String json = mapper.writeValueAsString(productService.add(entity)); out.append(json); } } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
運(yùn)行結(jié)果:
刪除:
二、延遲對象(Deferred)
deferred對象就是jQuery1.5版以后新增加的回調(diào)函數(shù)解決方案。
2.1、回調(diào)函數(shù)
先看一個(gè)示例:
首先,為什么要使用Deferred?
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>回調(diào)</title> </head> <body> <script src="js/jQuery1.11.3/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> var student; $.get("student.json",function(data){ student=data; },"json"); alert(student); </script> </body> </html>
student.json文件:{"name":"tom","id":"01"}
運(yùn)行結(jié)果:
因?yàn)锳JAX是異步執(zhí)行的,類似高級語言中的多線程,當(dāng)發(fā)起ajax請求時(shí)會有網(wǎng)絡(luò)延遲,而代碼并沒有在$.get的位置被阻塞,alert先執(zhí)行,但數(shù)據(jù)并沒有從遠(yuǎn)程獲取到,所以結(jié)果是undefined。
其實(shí)初學(xué)者經(jīng)常會犯這種錯(cuò)誤,如:
function getStudentById(id){ $.get("students.do",{"id":id},function(stu){ return stu; },"json"); }
上面的代碼是有問題的,原因如前面的示例是一樣的。怎么解決,如果你認(rèn)為是異步帶來的問題,當(dāng)然通過同步是可以解決的,如:
$.ajax({ type:"get", url:"student.json", async:false, /*非異步,同步*/ success:function(data){ student=data; } });
結(jié)果:
如果將所有的ajax請求修改為同步的,則ajax的好處就大打折扣了,如果即要異步又要解決上面的問題,可以使用回調(diào)方法。
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>回調(diào)</title> </head> <body> <script src="js/jQuery1.11.3/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> /*callback是一個(gè)當(dāng)ajax請求成功時(shí)的回調(diào)方法*/ function getStudent(callback) { $.get("student.json", function(data) { callback(data); }, "json"); } /*調(diào)用getStudent函數(shù),傳入?yún)?shù),參數(shù)也是一個(gè)函數(shù)*/ getStudent(function(stu){ alert(stu.id); }); /*把一個(gè)方法作為參數(shù)傳遞給另一個(gè)方法可以認(rèn)為是委托,如C++中的函數(shù)指針類似*/ getStudent(function(stu){ alert(stu.name); }); </script> </body> </html>
結(jié)果:
從這里看回調(diào)很完美,其實(shí)不然,實(shí)際開發(fā)中要復(fù)雜得多,如當(dāng)?shù)谝粋€(gè)ajax請求完成才可以完成第二個(gè),當(dāng)?shù)诙€(gè)完成才可以完成第三個(gè),可能最一個(gè)請求要等前面的所有請求都成功時(shí)才允許執(zhí)行或才有條件執(zhí)行,如
使用ajax編輯用戶信息,先加載用戶對象,再加載省,加載市,加縣,可能代碼會這樣寫:
$.get("url1",function(){ $.get("url2",function(){ $.get("url3",function(){ ... }); }); });
當(dāng)回調(diào)越來越多,嵌套越深,代碼可讀性就會越來越差。如果注冊了多個(gè)回調(diào),那更是一場噩夢,幸好從jQuery1.5開始出現(xiàn)了延遲對象(deferred),可以解決這個(gè)問題。
2.2、deferred.done
$.ajax()操作完成后,如果使用的是低于1.5.0版本的jQuery,返回的是XHR對象,你沒法進(jìn)行鏈?zhǔn)讲僮?;如果高?.5版,返回的是deferred對象,可以進(jìn)行鏈?zhǔn)讲僮鳌?/p>
當(dāng)延遲成功時(shí)調(diào)用一個(gè)函數(shù)或者數(shù)組函數(shù),功能與原success類似。
語法:deferred.done(doneCallbacks[,doneCallbacks])
返回值:Deferred Object
該參數(shù)可以是一個(gè)函數(shù)或一個(gè)函數(shù)的數(shù)組。當(dāng)延遲成功時(shí),doneCallbacks被調(diào)用?;卣{(diào)執(zhí)行是依照他們添加的順序。一旦deferred.done()返回延遲對象,延遲對象的其它方法也可以鏈接到了這里,包括增加.done()方法。當(dāng)延遲解決,doneCallbacks執(zhí)行使用參數(shù)提供給 resolve或 resolveWith方法依照添加的順序調(diào)用。
示例代碼:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>延遲對象(deferred)</title> </head> <body> <script src="js/jQuery1.11.3/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> console.log("使用方法一"); $.get("student.json", "json").done(function(stu) { console.log(stu.id); }).done(function(stu) { console.log(stu.name); }); console.log("使用方法二"); $.get("student.json", "json").done(function(stu) { console.log(stu.id); }, function(stu) { console.log(stu.name); }); </script> </body> </html>
運(yùn)行結(jié)果:
2.3、deferred.fail
語法:deferred.fail(failCallbacks[,failCallbacks])
返回值:Deferred Object
當(dāng)延遲失敗時(shí)調(diào)用一個(gè)函數(shù)或者數(shù)組函數(shù),功能與原回調(diào)方法error類似。
該參數(shù)可以是一個(gè)函數(shù)或一個(gè)函數(shù)的數(shù)組。當(dāng)延遲失敗時(shí),doneCallbacks被調(diào)用。回調(diào)執(zhí)行是依照他們添加的順序。一旦deferred.fail()返回延遲對象,延遲對象的其它方法也可以鏈接到了這里,包括增加.done()方法。當(dāng)延遲解決,doneCallbacks執(zhí)行使用參數(shù)提供給 resolve或 resolveWith方法依照添加的順序調(diào)用。
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>延遲對象(deferred)</title> </head> <body> <script src="js/jQuery1.11.3/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> $.get("stu.json", "json").done(function(stu) { console.log(stu.name); }).fail(function(xhr, status, errorThrown){ alert("xhr:"+xhr+",status:"+status+",errorThrown:"+errorThrown); }); </script> </body> </html>
運(yùn)行結(jié)果:
2.4、deferred.always
語法:deferred.always(alwaysCallbacks,[alwaysCallbacks])
返回值:Deferred Object
當(dāng)遞延對象是解決(成功,resolved)或拒絕(失敗,rejected)時(shí)被調(diào)用添加處理程序,與回調(diào)方法complete類似。
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>延遲對象(deferred)</title> </head> <body> <script src="js/jQuery1.11.3/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> $.get("student.j", "json").done(function(stu) { console.log(stu.name); }).fail(function(data, status, errorThrown){ console.log("data:"+data+",status:"+status+",errorThrown:"+errorThrown); }).always(function(data, textStatus){ console.log("ajax執(zhí)行完成,完成狀態(tài):"+textStatus); }); </script> </body> </html>
運(yùn)行結(jié)果
成功時(shí):
失敗時(shí):
2.5、deferred.then
deferred.then(doneFilter [, failFilter ] [, progressFilter ])
添加處理程序被調(diào)用時(shí),遞延對象得到解決或者拒絕,一次指定多個(gè)事件。
所有三個(gè)參數(shù)(包括progressCallbacks ,在jQuery的1.7 )可以是一個(gè)單獨(dú)的函數(shù)或一個(gè)函數(shù)的數(shù)組。 其中一個(gè)參數(shù),也可以為空,如果沒有該類型的回調(diào)是需要的?;蛘撸褂?done()或.fail()僅設(shè)置doneCallbacks或failCallbacks。當(dāng)遞延解決,doneCallbacks被調(diào)用。若遞延代替拒絕,failCallbacks被調(diào)用?;卣{(diào)按他們添加的順序執(zhí)行。一旦deferred.then返回延遲對象,延遲對象的其它方法也可以鏈接到了這里,包括增加.then()方法。
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>延遲對象(deferred)</title> </head> <body> <script src="js/jQuery1.11.3/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> $.get("student.jsonx", "json").then(function(stu) { console.log(stu.name); }, function(data, status, errorThrown) { console.log("data:" + data + ",status:" + status + ",errorThrown:" + errorThrown); }); </script> </body> </html>
結(jié)果:
2.6、應(yīng)用延遲對象
前面的示例中我們都是使用jQuery ajax返回的deferred對象,其實(shí)我們也可以在自定義的代碼中使用deferred對象,恰當(dāng)?shù)氖褂胐eferred對象或以優(yōu)雅的解決不少問題。
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>延遲對象(deferred)</title> </head> <body> <script src="js/jQuery1.11.3/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> var myTask=function(){ //通過jQuery創(chuàng)建一個(gè)延遲對象 var def=$.Deferred(); setTimeout(function(){ //隨機(jī)產(chǎn)生一個(gè)整數(shù),如果是偶數(shù) var n=Math.round(Math.random()*100); if(n%2==0) { console.log("一個(gè)耗時(shí)的操作終于完成了,n="+n); def.resolve(); //任務(wù)成功完成 }else{ console.log("一個(gè)耗時(shí)的操作失敗,n="+n); def.reject(); //拒絕,失敗 } },3000); //返回延遲對象,防止中間修改 return def.promise(); } /*當(dāng)方法myTask執(zhí)行完成后,添加回調(diào)方法*/ $.when(myTask()).done(function(){ console.log("執(zhí)行成功"); }).fail(function(){ console.log("執(zhí)行失敗"); }); </script> </body> </html>
失敗時(shí):
成功時(shí):
promise()在原來的deferred對象上返回另一個(gè)deferred對象,后者只開放與改變執(zhí)行狀態(tài)無關(guān)的方法(比如done()方法和fail()方法),屏蔽與改變執(zhí)行狀態(tài)有關(guān)的方法(比如resolve()方法和reject()方法),從而使得執(zhí)行狀態(tài)不能被改變。
2.7、總結(jié)
(1) 生成一個(gè)對象?! ?/p>
- 指定操作成功時(shí)的回調(diào)函數(shù)
- 指定操作失敗時(shí)的回調(diào)函數(shù)
- 沒有參數(shù)時(shí),返回一個(gè)新的對象,該對象的運(yùn)行狀態(tài)無法被改變;接受參數(shù)時(shí),作用為在參數(shù)對象上部署接口?! ?/li>
- 手動(dòng)改變對象的運(yùn)行狀態(tài)為已完成,從而立即觸發(fā)方法?! ?/li>
- 這個(gè)方法與正好相反,調(diào)用后將對象的運(yùn)行狀態(tài)變?yōu)橐咽?,從而立即觸發(fā)方法?! ?/li>
- .Deferred()生成一個(gè)deferred對象?! ?/li>
(2)deferred.done()指定操作成功時(shí)的回調(diào)函數(shù)
(3)deferred.fail()指定操作失敗時(shí)的回調(diào)函數(shù)
(4)deferred.promise()沒有參數(shù)時(shí),返回一個(gè)新的deferred對象,該對象的運(yùn)行狀態(tài)無法被改變;接受參數(shù)時(shí),作用為在參數(shù)對象上部署deferred接口。
(5)deferred.resolve()手動(dòng)改變deferred對象的運(yùn)行狀態(tài)為"已完成",從而立即觸發(fā)done()方法?! ?/p>
(6)deferred.reject()這個(gè)方法與deferred.resolve()正好相反,調(diào)用后將deferred對象的運(yùn)行狀態(tài)變?yōu)?已失敗",從而立即觸發(fā)fail()方法。
(7).when() 為多個(gè)操作指定回調(diào)函數(shù)。
除了這些方法以外,deferred對象還有二個(gè)重要方法,上面的教程中沒有涉及到。
(8)deferred.then()
有時(shí)為了省事,可以把done()和fail()合在一起寫,這就是then()方法。
如果then()有兩個(gè)參數(shù),那么第一個(gè)參數(shù)是done()方法的回調(diào)函數(shù),第二個(gè)參數(shù)是fail()方法的回調(diào)方法。如果then()只有一個(gè)參數(shù),那么等同于done()。
(9)deferred.always()
這個(gè)方法也是用來指定回調(diào)函數(shù)的,它的作用是,不管調(diào)用的是deferred.resolve()還是deferred.reject(),最后總是執(zhí)行。
三、跨域
互聯(lián)網(wǎng)上的主機(jī)由IP來標(biāo)識,為了方便記憶,創(chuàng)建了域名系統(tǒng).域名與IP對應(yīng),域名的作用是不用讓你記復(fù)雜的IP地址,能唯一定位資源,URL的格式是協(xié)議://主機(jī)名.公司名稱.機(jī)構(gòu)類型.地域類型:端口/路徑,如http://www.zhangguo.com.cn:8080/products/list.do?id=1#a1
3.1、什么是跨域
JavaScript同源策略的限制,A域名下的JavaScript無法操作B或是C域名下的對象,如下所示:
假設(shè)頁面:http://store.company.com/index.html
客戶端代碼d05.html,http://localhost:8087/jQuery601_JAVA/d05.html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>6.4.9、跨域AJAX請求</title> </head> <body> <h2>6.4.9、跨域AJAX請求</h2> <h2 id="message"></h2> <button type="button" id="btnAjax">ajax請求</button> <script type="text/javascript" src="js/jQuery/jquery.min.js"></script> <script type="text/javascript"> $("#btnAjax").click(function() { $.get("http://localhost:12833/Action/FindUserById.ashx",{"id":1001},function(data){ log(data); },"text"); }); function log(msg) { $("#message")[0].innerHTML += msg + "<br/>"; } </script> </body> </html>
另一個(gè)域下面一般處理程序,http://localhost:12833/Action/FindUserById.ashx:
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace jQuery601_DotNet.Action { /// <summary> /// 根據(jù)用戶編號獲得用戶 /// </summary> public class FindUserById : IHttpHandler { public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/plain"; String name = ""; int id = Convert.ToInt32(context.Request.Params["id"]); if (id == 1001) { name = "Mark"; } else if (id == 1002) { name = "Jack"; } context.Response.Write(name); } public bool IsReusable { get { return false; } } } }
運(yùn)行結(jié)果:
3.2、JSONP跨域
JSONP跨域是利用script腳本允許引用不同域下的js實(shí)現(xiàn)的,將回調(diào)方法帶入服務(wù)器,返回結(jié)果時(shí)回調(diào)。
2.1、JSONP跨域原理
客戶端:
<body> <script type="text/javascript"> /*回調(diào)方法*/ function show(data) { alert(data); } </script> <script src="http://localhost:8087/JavaScript001/Product?act=area&callback=show" type="text/javascript" charset="utf-8"></script> </body>
服務(wù)器:
String callback=request.getParameter("callback"); out.append(callback+"('"+new Date()+"')");
結(jié)果:
服務(wù)器返回一段javascript,通過指定的方法名調(diào)用。從圖中可以看出,使用JSONP的形式調(diào)用已經(jīng)不再是通過XMLHTTPRequest對象,而是同步調(diào)用。
3.3、jQuery使用JSONP跨域
在jQuery中內(nèi)置了實(shí)現(xiàn)JSONP跨域的功能,如果指定為json類型,則會把獲取到的數(shù)據(jù)作為一個(gè)JavaScript對象來解析,并且把構(gòu)建好的對象作為結(jié)果返回。為了實(shí)現(xiàn)這個(gè)目的,他首先嘗試使用JSON.parse()。如果瀏覽器不支持,則使用一個(gè)函數(shù)來構(gòu)建。JSON數(shù)據(jù)是一種能很方便通過JavaScript解析的結(jié)構(gòu)化數(shù)據(jù)。如果獲取的數(shù)據(jù)文件存放在遠(yuǎn)程服務(wù)器上(域名不同,也就是跨域獲取數(shù)據(jù)),則需要使用jsonp類型。使用這種類型的話,會創(chuàng)建一個(gè)查詢字符串參數(shù) callback=? ,這個(gè)參數(shù)會加在請求的URL后面。服務(wù)器端應(yīng)當(dāng)在JSON數(shù)據(jù)前加上回調(diào)函數(shù)名,以便完成一個(gè)有效的JSONP請求。如果要指定回調(diào)函數(shù)的參數(shù)名來取代默認(rèn)的callback,可以通過設(shè)置$.ajax()的jsonp參數(shù)。
頁面腳本:
<body> <script type="text/javascript"> /*回調(diào)方法*/ function show(data) { alert(data); } </script> <script src="http://localhost:8087/JavaScript001/Product?act=area&callback=show" type="text/javascript" charset="utf-8"></script> </body>
服務(wù)器一般處理程序:
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace jQuery601_DotNet.Action { /// <summary> /// FindUserById 的摘要說明 /// </summary> public class FindUserById : IHttpHandler { public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/plain"; String name = ""; int id = Convert.ToInt32(context.Request.Params["id"]); if (id == 1001) { name = "Mark"; } else if (id == 1002) { name = "Jack"; } String callback = context.Request["callback"]; context.Response.Write(callback+"('"+name+"')"); } public bool IsReusable { get { return false; } } } }
運(yùn)行結(jié)果:
服務(wù)器Servlet:
package com.gomall.action; import java.io.IOException; import java.io.PrintWriter; import java.util.Date; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.codehaus.jackson.map.ObjectMapper; import com.gomall.service.IProductService; import com.gomall.service.ProductService; @WebServlet("/Product") public class Product extends HttpServlet { private static final long serialVersionUID = 1L; public Product() { super(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); response.setCharacterEncoding("utf-8"); String act = request.getParameter("act"); IProductService productService = new ProductService(); ObjectMapper mapper = new ObjectMapper(); PrintWriter out=response.getWriter(); if (act.equals("getAll")) { String json = mapper.writeValueAsString(productService.getAll()); out.append(json); } else if (act.equals("area")) { String callback=request.getParameter("callback"); out.append(callback+"('"+new Date()+"')"); } else if (act.equals("getJSONP")) { String callback=request.getParameter("callback"); String json = mapper.writeValueAsString(productService.getAll()); out.append(callback+"("+json+")"); } } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
客戶端:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>AJAX</title> </head> <body> <script src="js/jQuery1.11.3/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> $.get("http://localhost:8087/JavaScript001/Product?callback=?",{act:"getJSONP"},function(data){ $.each(data,function(index,obj){ $("<p/>").html(obj.name).appendTo("body"); }); },"jsonp"); </script> </body> </html>
運(yùn)行結(jié)果:
在jQuery中如果使用JSONP只需要將返回?cái)?shù)據(jù)類型設(shè)置為jsonp就可以了,但是這種方法只支持get請求,不支持post請求;請求是同步的;服務(wù)器返回?cái)?shù)據(jù)要處理,要添加回調(diào)函數(shù),麻煩。
3.4、跨域資源共享(CORS)
跨域資源共享(CORS)是一種網(wǎng)絡(luò)瀏覽器的技術(shù)規(guī)范,它為Web服務(wù)器定義了一種方式,允許網(wǎng)頁從不同的域訪問其資源。
CORS與JSONP相比:
1、 JSONP只能實(shí)現(xiàn)GET請求,而CORS支持所有類型的HTTP請求。
2、 使用CORS,開發(fā)者可以使用普通的XMLHttpRequest發(fā)起請求和獲得數(shù)據(jù),比起JSONP有更好的錯(cuò)誤處理。
3、 JSONP主要被老的瀏覽器支持,它們往往不支持CORS,而絕大多數(shù)現(xiàn)代瀏覽器都已經(jīng)支持了CORS。
CORS有兩種模型可以實(shí)現(xiàn):
1.簡單模型
支持get/post/put/delete請求,例如返回Access-Control-Allow-Origin:*,但是不允許自定義header且會忽略cookies,且post數(shù)據(jù)格式有限制,只支持‘text/plain','application/x-www-urlencoded'and'multipart/form-data',其中'text/plain'默認(rèn)支持,后面兩種需要下面的預(yù)檢請求和服務(wù)器協(xié)商。
2.協(xié)商模型/預(yù)檢請求(Preflighted Request)
舉例:瀏覽器發(fā)出PUT請求,OPTION請求返回Access-Control-Allow-Origin:*,Access-Control-Allow-Methods:'PUT',服務(wù)器同意所有域的PUT請求,瀏覽器收到并繼續(xù)發(fā)出真正的PUT請求,服務(wù)器響應(yīng)并再次返回Access-Control-Allow-Origin:*,允許瀏覽器的腳本執(zhí)行服務(wù)器返回的數(shù)據(jù)。
response.addHeader("Access-Control-Allow-Origin","
Access-Control-Allow-Origin:允許跨域訪問的域名,如果是公共的則返回*即可
response.addHeader("Access-Control-Allow-Methods","GET,POST,OPTIONS");
Access-Control-Allow-Methods:允許跨域訪問的謂詞(方法),如GET,POST,DELETE,PUT(REST)
.Net服務(wù)器一般處理程序代碼:
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace jQuery601_DotNet.Action { /// <summary> /// FindUserById 的摘要說明 /// </summary> public class FindUserById : IHttpHandler { public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/plain"; context.Response.Headers.Add("Access-Control-Allow-Origin","*"); context.Response.Headers.Add("Access-Control-Allow-Methods", "GET,POST"); String name = ""; int id = Convert.ToInt32(context.Request.Params["id"]); if (id == 1001) { name = "Mark"; } else if (id == 1002) { name = "Jack"; } context.Response.Write(name); } public bool IsReusable { get { return false; } } } }
客戶端腳本:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>6.4.9、跨域AJAX請求</title> </head> <body> <h2>6.4.9、跨域AJAX請求</h2> <h2 id="message"></h2> <button type="button" id="btnAjax">ajax請求</button> <script type="text/javascript" src="js/jQuery/jquery.min.js"></script> <script type="text/javascript"> $("#btnAjax").click(function() { $.get("http://localhost:12833/Action/FindUserById.ashx",{"id":1001},function(data){ log(data); },"text"); }); function log(msg) { $("#message")[0].innerHTML += msg + "<br/>"; } </script> </body> </html>
運(yùn)行結(jié)果:
從上圖可以看到實(shí)現(xiàn)跨域且為異步請求。
Java Servlet后臺腳本:
package com.gomall.action; import java.io.IOException; import java.io.PrintWriter; import java.util.Date; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.codehaus.jackson.map.ObjectMapper; import com.gomall.service.IProductService; import com.gomall.service.ProductService; @WebServlet("/Product") public class Product extends HttpServlet { private static final long serialVersionUID = 1L; public Product() { super(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); response.setCharacterEncoding("utf-8"); String act = request.getParameter("act"); IProductService productService = new ProductService(); ObjectMapper mapper = new ObjectMapper(); PrintWriter out=response.getWriter(); if (act.equals("getAll")) { String json = mapper.writeValueAsString(productService.getAll()); out.append(json); } else if (act.equals("area")) { String callback=request.getParameter("callback"); out.append(callback+"('"+new Date()+"')"); } else if (act.equals("getJSONP")) { String callback=request.getParameter("callback"); String json = mapper.writeValueAsString(productService.getAll()); out.append(callback+"("+json+")"); } else if (act.equals("getAllCORS")) { /**向響應(yīng)的頭部中添加內(nèi)容*/ response.addHeader("Access-Control-Allow-Origin", "*"); response.addHeader("Access-Control-Allow-Methods", "GET,POST"); String json = mapper.writeValueAsString(productService.getAll()); out.append(json); } } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
客戶端代碼:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>AJAX</title> </head> <body> <script src="js/jQuery1.11.3/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> $.get("http://localhost:8087/JavaScript001/Product?act=getAllCORS",function(data){ alert(data); }); </script> </body> </html>
運(yùn)行結(jié)果:
2.4、CORS跨域的問題
a)、如果認(rèn)為每次需要修改HTTP頭部比較麻煩,在java中可以使用過濾器,.Net可以使用Module或HttpHandler全局注冊(注冊到Web.Config中,部署時(shí)還需要注意)。
b)、如果需要考慮IE8實(shí)現(xiàn)CORS則要插件支持,因?yàn)镮E8并沒有完全支持CORS。
插件名稱:javascript-jquery-transport-xdr
github: https://github.com/gfdev/javascript-jquery-transport-xdr
示例代碼:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>AJAX</title> </head> <body> <script src="js/jQuery1.11.3/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script> <!--[if (IE 8)|(IE 9)]> <script src="js/jquery.transport.xdr.min.js" type="text/javascript" charset="utf-8"></script> <![endif]--> <script type="text/javascript"> $.get("http://localhost:8087/JavaScript001/Product?act=getAllCORS&type=meat-and-filler&format=json",{},function(data){ alert(data); },"json"); </script> </body> </html>
運(yùn)行結(jié)果:
c)、Apache官方提供一個(gè)支持CORS跨域的過濾器,詳細(xì)說明: http://tomcat.apache.org/tomcat-7.0-doc/config/filter.html
3.5、小結(jié)
當(dāng)然除了兼容老瀏覽器的jsonp跨域與HTML5中的CORS跨域還有很多其它辦法如利用iframe和location.hash、window.name實(shí)現(xiàn)的跨域數(shù)據(jù)傳輸、使用HTML5 postMessage、利用flash等辦法。個(gè)人認(rèn)為CORS應(yīng)該才是未來主要的跨域選擇,其它的方法都只是hack。
四、彈出層
前面AJAX示例中添加功能如果放在一個(gè)彈出層中布局會更加緊湊一些,像登錄,提示信息經(jīng)常會需要彈出層。
常見的彈出層有:FancyBox,LightBox,colorBox,artDialog,BlockUI,Layer等,這里介紹騰訊開源的artDialog,輕量,實(shí)用。
artDialog是一個(gè)設(shè)計(jì)得十分巧妙的對話框組件,小巧身材卻擁有豐富的接口與漂亮的外觀。
特點(diǎn)是自適應(yīng)內(nèi)容、優(yōu)雅的接口、細(xì)致的體驗(yàn)、跨平臺兼容、輕量實(shí)用。
項(xiàng)目源碼: https://github.com/aui/artDialog
幫助信息: http://img0.zz91.com/huanbao/mblog/artDialog-5.0.4
文檔與示例: http://aui.github.io/artDialog/doc/index.html
AngularJS 版本: https://github.com/aui/angular-popups
使用方法:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>artDialog</title> </head> <body> <button onclick="btn_dialog()"> 彈出框 </button> <button onclick="btn_loading()"> 加載中 </button> <script src="js/jQuery1.11.3/jquery-1.11.3.js" type="text/javascript" charset="utf-8"></script> <script src="js/artDialog6/dialog-min.js" type="text/javascript" charset="utf-8"></script> <link rel="stylesheet" type="text/css" href="js/artDialog6/ui-dialog.css" /> <script type="text/javascript"> function btn_dialog() { var d = dialog({ title: '消息', content: '風(fēng)吹起的青色衣衫,夕陽里的溫暖容顏,你比以前更加美麗,像盛開的花<br>——許巍《難忘的一天》', okValue: '確 定', ok: function() { var that = this; setTimeout(function() { that.title('提交中..'); }, 2000); return false; }, cancelValue: '取消', cancel: function() { alert('你點(diǎn)了取消按鈕') } }); d.show(); } function btn_loading(){ dialog({ modal:true }).show(); } </script> </body> </html>
運(yùn)行結(jié)果:
屬性:
// 對齊方式 //align: 'bottom left', // 是否固定定位 //fixed: false, // 對話框疊加高度值(重要:此值不能超過瀏覽器最大限制) //zIndex: 1024, // 設(shè)置遮罩背景顏色 backdropBackground: '#000', // 設(shè)置遮罩透明度 backdropOpacity: 0.7, // 消息內(nèi)容 content: '<span class="ui-dialog-loading">Loading..</span>', // 標(biāo)題 title: '', // 對話框狀態(tài)欄區(qū)域 HTML 代碼 statusbar: '', // 自定義按鈕 button: null, // 確定按鈕回調(diào)函數(shù) ok: null, // 取消按鈕回調(diào)函數(shù) cancel: null, // 確定按鈕文本 okValue: 'ok', // 取消按鈕文本 cancelValue: 'cancel', cancelDisplay: true, // 內(nèi)容寬度 width: '', // 內(nèi)容高度 height: '', // 內(nèi)容與邊界填充距離 padding: '', // 對話框自定義 className skin: '', // 是否支持快捷關(guān)閉(點(diǎn)擊遮罩層自動(dòng)關(guān)閉) quickClose: false, // css 文件路徑,留空則不會使用 js 自動(dòng)加載樣式 // 注意:css 只允許加載一個(gè) cssUri: '../css/ui-dialog.css',
事件:
/** * 顯示對話框 * @name artDialog.prototype.show * @param {HTMLElement Object, Event Object} 指定位置(可選) */ /** * 顯示對話框(模態(tài)) * @name artDialog.prototype.showModal * @param {HTMLElement Object, Event Object} 指定位置(可選) */ /** * 關(guān)閉對話框 * @name artDialog.prototype.close * @param {String, Number} 返回值,可被 onclose 事件收?。蛇x) */ /** * 銷毀對話框 * @name artDialog.prototype.remove */ /** * 重置對話框位置 * @name artDialog.prototype.reset */ /** * 讓對話框聚焦(同時(shí)置頂) * @name artDialog.prototype.focus */ /** * 讓對話框失焦(同時(shí)置頂) * @name artDialog.prototype.blur */ /** * 添加事件 * @param {String} 事件類型 * @param {Function} 監(jiān)聽函數(shù) * @name artDialog.prototype.addEventListener */ /** * 刪除事件 * @param {String} 事件類型 * @param {Function} 監(jiān)聽函數(shù) * @name artDialog.prototype.removeEventListener */ /** * 對話框顯示事件,在 show()、showModal() 執(zhí)行 * @name artDialog.prototype.onshow * @event */ /** * 關(guān)閉事件,在 close() 執(zhí)行 * @name artDialog.prototype.onclose * @event */ /** * 銷毀前事件,在 remove() 前執(zhí)行 * @name artDialog.prototype.onbeforeremove * @event */ /** * 銷毀事件,在 remove() 執(zhí)行 * @name artDialog.prototype.onremove * @event */ /** * 重置事件,在 reset() 執(zhí)行 * @name artDialog.prototype.onreset * @event */ /** * 焦點(diǎn)事件,在 foucs() 執(zhí)行 * @name artDialog.prototype.onfocus * @event */ /** * 失焦事件,在 blur() 執(zhí)行 * @name artDialog.prototype.onblur * @event */
該插件使用比較簡單,可以看示例與源代碼。
五、模板引擎
在AJAX示例中javascript中有大量的html字符串,html中有一些像onclick樣的javascript,這樣javascript中有html,html中有javascript,代碼的偶合度很高,不便于修改與維護(hù),使用模板引擎可以解決問題。
模板引擎(這里特指用于Web開發(fā)的模板引擎)是為了使用戶界面與業(yè)務(wù)數(shù)據(jù)(內(nèi)容)分離而產(chǎn)生的,它可以生成特定格式的文檔,用于網(wǎng)站的模板引擎就會生成一個(gè)標(biāo)準(zhǔn)的HTML文檔。前后端都有模板引擎,比如T4、FreeMarker、Velocity,這里主要講前端模板引擎:
上圖是常見的一些前端模板引擎,速度相對快的是artTemplate,與artDialog是同一個(gè)作者,當(dāng)然一個(gè)好的模板引擎不僅是速度還有很多方面都關(guān)鍵。
源碼與幫助: https://github.com/aui/artTemplate
5.1、Hello World
示例代碼:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>artTemplate</title> </head> <body> <div id="result"> </div> <script src="js/artTemplate3/template.js" type="text/javascript" charset="utf-8"></script> <script type="text/html" id="template1"> {{if isShow}} <h2>姓名:{{name}}</h2> <ul> {{each hobbies as hobby index}} <li> {{index+1}} {{hobby}} </li> {{/each}} </ul> {{/if}} </script> <script type="text/javascript"> var data={ isShow:true, name:"Tom", hobbies:["看書","上網(wǎng)","運(yùn)動(dòng)","電影","購物"] }; //用數(shù)據(jù)與模板渲染(render)出結(jié)果 var html=template("template1",data); document.getElementById("result").innerHTML=html; </script> </body> </html>
運(yùn)行結(jié)果:
生成的代碼:
<h2>姓名:Tom</h2> <ul> <li> 看書 </li> <li> 上網(wǎng) </li> <li> 運(yùn)動(dòng) </li> <li> 電影 </li> <li> 購物 </li> </ul>
5.2、方法
1)、template(id, data)
根據(jù) id 渲染模板。內(nèi)部會根據(jù)document.getElementById(id)查找模板。
如果沒有 data 參數(shù),那么將返回一渲染函數(shù)。
2)、template.compile(source, options)
將返回一個(gè)渲染函數(shù)。演示
3)、template.render(source, options)
將返回渲染結(jié)果。
4)、template.helper(name, callback)
添加輔助方法,讓模板引擎調(diào)用自定義的javascript方法。
5)、template.config(name, value)
示例代碼:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>artTemplate</title> </head> <body> <div id="result"> </div> <script src="js/artTemplate3/template.js" type="text/javascript" charset="utf-8"></script> <script type="text/html" id="template1"> $$if isShow## <h2>姓名:$$name##</h2> <ul> $$include "template2"## <!--包含模板2--> </ul> $$/if## </script> <script type="text/html" id="template2"> $$each hobbies as hobby index## <li> $$index+1## $$#hobby## <!--默認(rèn)會轉(zhuǎn)義,加#號不轉(zhuǎn)義--> </li> $$/each## </script> <script type="text/javascript"> var data={ isShow:true, name:"Tom", hobbies:["看書","上網(wǎng)","運(yùn)動(dòng)","<b>電影</b>","<i>購物</i>"] }; //邏輯語法開始標(biāo)簽 template.config("openTag","$$"); //邏輯語法結(jié)束標(biāo)簽 template.config("closeTag","##"); //不轉(zhuǎn)義 template.config("escape",false); //用數(shù)據(jù)與模板渲染(render)出結(jié)果 var html=template("template1",data); document.getElementById("result").innerHTML=html; </script> </body> </html>
運(yùn)行結(jié)果:
5.3、與AJAX結(jié)合應(yīng)用
示例腳本:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>商品管理</title> <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" /> <style type="text/css"> @CHARSET "UTF-8"; * { margin: 0; padding: 0; font-family: microsoft yahei; font-size: 14px; } body { padding-top: 20px; } .main { width: 90%; margin: 0 auto; border: 1px solid #777; padding: 20px; } .main .title { font-size: 20px; font-weight: normal; border-bottom: 1px solid #ccc; margin-bottom: 15px; padding-bottom: 5px; color: blue; } .main .title span { display: inline-block; font-size: 20px; background: blue; color: #fff; padding: 0 8px; background: blue; } a { color: blue; text-decoration: none; } a:hover { color: orangered; } .tab td, .tab, .tab th { border: 1px solid #777; border-collapse: collapse; } .tab td, .tab th { line-height: 26px; height: 26px; padding-left: 5px; } .abtn { display: inline-block; height: 20px; line-height: 20px; background: blue; color: #fff; padding: 0 5px; } .btn { height: 20px; line-height: 20px; background: blue; color: #fff; padding: 0 8px; border: 0; } .abtn:hover, .btn:hover { background: orangered; color: #fff; } p { padding: 5px 0; } fieldset { border: 1px solid #ccc; padding: 5px 10px; } fieldset legend { margin-left: 10px; font-size: 16px; } .pic { height: 30px; width: auto; } #divFrom { display: none; } </style> </head> <body> <div class="main"> <h2 class="title"><span>商品管理</span></h2> <table border="1" width="100%" class="tab" id="tabGoods"> <tr> <th>編號</th> <th>圖片</th> <th>商品名</th> <th>價(jià)格</th> <th>詳細(xì)</th> <th>操作</th> </tr> </table> <p style="color: red" id="message"></p> <p> <a href="#" class="abtn" id="btnSave">添加</a> <input type="submit" value="刪除選擇項(xiàng)" class="btn" /> </p> <div id="divFrom"> <form id="formPdt"> <fieldset> <legend>添加商品</legend> <p> <label for="name"> 名稱: </label> <input type="text" name="name" id="name" /> </p> <p> <label for="price"> 價(jià)格: </label> <input type="text" name="price" id="price" /> </p> <p> <label for="detail"> 詳細(xì): </label> <textarea id="detail" name="detail" cols="60"></textarea> </p> </fieldset> </form> </div> </div> <link rel="stylesheet" type="text/css" href="js/artDialog6/ui-dialog.css" /> <script src="js/artTemplate3/template.js" type="text/javascript" charset="utf-8"></script> <script src="js/jQuery1.11.3/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script> <script src="js/artDialog6/dialog-min.js" type="text/javascript" charset="utf-8"></script> <!--[if (IE 8)|(IE 9)]> <script src="js/jquery.transport.xdr.min.js" type="text/javascript" charset="utf-8"></script> <![endif]--> <script type="text/html" id="tmpl"> {{each list as pdt}} <tr> <td>{{pdt.id}}</td> <td><img src="http://localhost:8087/JavaScript001/images/{{pdt.picture}}" class="pic"></td> <td>{{pdt.name}}</td> <td>{{pdt.price | round:'¥'}}</td> <td>{{pdt.detail}}</td> <td> <a href="#" class="abtn del" data-id={{pdt.id}}>刪除</a> </td> </tr> {{/each}} </script> <script type="text/javascript"> var app = { url: "http://localhost:8087/JavaScript001/", //提供服務(wù)的域名 add: function() { var d = dialog({ title: '添加商品', content: $('#divFrom').html(), okValue: '添加', modal: true, backdropOpacity: 0.3, ok: function() { var that = this; $.ajax({ type: "post", data: $(".ui-dialog #formPdt").serialize() + "&act=add", success: function(data) { if(data) { app.log("添加成功!"); app.loadAll(); that.close(); } else { app.log("添加失敗!"); } } }); return false; }, cancelValue: '關(guān)閉', cancel: function() { alert('你點(diǎn)了取消按鈕') }, onclose: function() { alert("關(guān)閉了"); } }); d.show(); }, del: function() { id = $(this).data("id"); var that = $(this); $.ajax({ type: "get", data: { "id": id, "act": "del" }, success: function(data) { if(data) { that.closest("tr").remove(); app.log("刪除成功!"); } else { app.log("刪除失敗!"); } } }); }, loadAll: function() { $.ajax({ type: "get", data: { "act": "getAllCORS" }, success: function(data) { $("#tabGoods tr:gt(0)").remove(); $("#tabGoods").append(template("tmpl",{list:data})); } }); }, init: function() { /*動(dòng)態(tài)綁定刪除事件*/ $("#tabGoods").on("click", "a.del", {}, app.del); /*綁定添加事件*/ $("#btnSave").click(app.add); /*設(shè)置全局AJAX默認(rèn)值*/ $.ajaxSetup({ dataType: "json", url: app.url + "Product?type=meat-and-filler&format=json", beforeSend: app.ajaxBefore, complete: app.clearMsg, error: function(xhr, textStatus, errorThrown) { app.log("錯(cuò)誤" + textStatus + errorThrown); } }); //為模板引擎定義輔助函數(shù) template.helper("round",function(value,mark){ return (mark||"")+Math.round(value); }); this.loadAll(); }, clearMsg: function() { this.box.remove(); }, ajaxBefore: function() { this.box = dialog({ modal: true }); this.box.show(); }, log: function(msg) { $("#message").html(msg); } }; app.init(); </script> </body> </html>
運(yùn)行結(jié)果:
六、示例下載
coding: http://xiazai.jb51.net/201612/yuanma/zhangguo5-javascript001-master_jb51.rar
服務(wù)器: http://xiazai.jb51.net/201612/yuanma/zhangguo5-javascript001_java-master_jb51.rar
github: http://xiazai.jb51.net/201612/yuanma/javascript01-master_jb51.rar
以上就是本文的全部內(nèi)容,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,同時(shí)也希望多多支持腳本之家!
- Ajax實(shí)現(xiàn)搜索引擎自動(dòng)補(bǔ)全功能
- JavaScript的History API使搜索引擎抓取AJAX內(nèi)容
- 如何讓搜索引擎抓取AJAX內(nèi)容解決方案
- AJAX 支持搜索引擎問題分析
- 淺析ajax請求json數(shù)據(jù)并用js解析(示例分析)
- Ajax請求中的異步與同步,需要注意的地方說明
- AJAX跨域請求json數(shù)據(jù)的實(shí)現(xiàn)方法
- 原生 JS Ajax,GET和POST 請求實(shí)例代碼
- Ajax請求二進(jìn)制流進(jìn)行處理(ajax異步下載文件)的簡單方法
- Ajax引擎 ajax請求步驟詳細(xì)代碼
相關(guān)文章
老生常談document.ready和window.onload
這篇文章主要介紹了document.ready和window.onload的相關(guān)知識,包括document.ready和window.onload的區(qū)別,要使用document.ready()或者document.onload()的原因分析,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧2024-01-01用js限制網(wǎng)頁只在微信瀏覽器中打開(或者只能手機(jī)端訪問)
這篇文章主要介紹了用js限制網(wǎng)頁只在微信瀏覽器中打開,很多電影站也是這么限制的,原因你懂的,需要的朋友可以參考下2020-01-01JS將數(shù)字轉(zhuǎn)換成三位逗號分隔的樣式(示例代碼)
本篇文章主要是對JS將數(shù)字轉(zhuǎn)換成三位逗號分隔的樣式(示例代碼)進(jìn)行了介紹,需要的朋友可以過來參考下,希望對大家有所幫助2014-02-02原生JS實(shí)現(xiàn)旋轉(zhuǎn)輪播圖+文字內(nèi)容切換效果【附源碼】
這篇文章主要介紹了原生JS實(shí)現(xiàn)旋轉(zhuǎn)輪播圖+文字內(nèi)容切換效果,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-09-09JS去除重復(fù)并統(tǒng)計(jì)數(shù)量的實(shí)現(xiàn)方法
js去除重復(fù)并統(tǒng)計(jì)數(shù)量方法,首先點(diǎn)擊按鈕觸發(fā)事件,然后用class選擇器,迭代要獲取的文本(這里最好用text()方法)加入到Array()集合里。具體操作方法,大家通過本文學(xué)習(xí)下吧2016-12-12JS樹形結(jié)構(gòu)根據(jù)id獲取父級節(jié)點(diǎn)元素的示例代碼
這篇文章主要介紹了JS樹形結(jié)構(gòu)根據(jù)id獲取父級節(jié)點(diǎn)元素,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-05-05