詳解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;
/** 價格 */
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ò)延時*/
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ù)
先看一個示例:
首先,為什么要使用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請求時會有網(wǎng)絡(luò)延遲,而代碼并沒有在$.get的位置被阻塞,alert先執(zhí)行,但數(shù)據(jù)并沒有從遠(yuǎn)程獲取到,所以結(jié)果是undefined。
其實(shí)初學(xué)者經(jīng)常會犯這種錯誤,如:
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是一個當(dāng)ajax請求成功時的回調(diào)方法*/
function getStudent(callback) {
$.get("student.json", function(data) {
callback(data);
}, "json");
}
/*調(diào)用getStudent函數(shù),傳入?yún)?shù),參數(shù)也是一個函數(shù)*/
getStudent(function(stu){
alert(stu.id);
});
/*把一個方法作為參數(shù)傳遞給另一個方法可以認(rèn)為是委托,如C++中的函數(shù)指針類似*/
getStudent(function(stu){
alert(stu.name);
});
</script>
</body>
</html>
結(jié)果:

從這里看回調(diào)很完美,其實(shí)不然,實(shí)際開發(fā)中要復(fù)雜得多,如當(dāng)?shù)谝粋€ajax請求完成才可以完成第二個,當(dāng)?shù)诙€完成才可以完成第三個,可能最一個請求要等前面的所有請求都成功時才允許執(zhí)行或才有條件執(zhí)行,如
使用ajax編輯用戶信息,先加載用戶對象,再加載省,加載市,加縣,可能代碼會這樣寫:
$.get("url1",function(){
$.get("url2",function(){
$.get("url3",function(){
...
});
});
});
當(dāng)回調(diào)越來越多,嵌套越深,代碼可讀性就會越來越差。如果注冊了多個回調(diào),那更是一場噩夢,幸好從jQuery1.5開始出現(xiàn)了延遲對象(deferred),可以解決這個問題。
2.2、deferred.done
$.ajax()操作完成后,如果使用的是低于1.5.0版本的jQuery,返回的是XHR對象,你沒法進(jìn)行鏈?zhǔn)讲僮?;如果高?.5版,返回的是deferred對象,可以進(jìn)行鏈?zhǔn)讲僮鳌?/p>
當(dāng)延遲成功時調(diào)用一個函數(shù)或者數(shù)組函數(shù),功能與原success類似。
語法:deferred.done(doneCallbacks[,doneCallbacks])
返回值:Deferred Object
該參數(shù)可以是一個函數(shù)或一個函數(shù)的數(shù)組。當(dāng)延遲成功時,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)延遲失敗時調(diào)用一個函數(shù)或者數(shù)組函數(shù),功能與原回調(diào)方法error類似。
該參數(shù)可以是一個函數(shù)或一個函數(shù)的數(shù)組。當(dāng)延遲失敗時,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)時被調(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é)果
成功時:

失敗時:

2.5、deferred.then
deferred.then(doneFilter [, failFilter ] [, progressFilter ])
添加處理程序被調(diào)用時,遞延對象得到解決或者拒絕,一次指定多個事件。
所有三個參數(shù)(包括progressCallbacks ,在jQuery的1.7 )可以是一個單獨(dú)的函數(shù)或一個函數(shù)的數(shù)組。 其中一個參數(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)建一個延遲對象
var def=$.Deferred();
setTimeout(function(){
//隨機(jī)產(chǎn)生一個整數(shù),如果是偶數(shù)
var n=Math.round(Math.random()*100);
if(n%2==0)
{
console.log("一個耗時的操作終于完成了,n="+n);
def.resolve(); //任務(wù)成功完成
}else{
console.log("一個耗時的操作失敗,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>
失敗時:

成功時:

promise()在原來的deferred對象上返回另一個deferred對象,后者只開放與改變執(zhí)行狀態(tài)無關(guān)的方法(比如done()方法和fail()方法),屏蔽與改變執(zhí)行狀態(tài)有關(guān)的方法(比如resolve()方法和reject()方法),從而使得執(zhí)行狀態(tài)不能被改變。
2.7、總結(jié)
(1) 生成一個對象?! ?/p>
- 指定操作成功時的回調(diào)函數(shù)
- 指定操作失敗時的回調(diào)函數(shù)
- 沒有參數(shù)時,返回一個新的對象,該對象的運(yùn)行狀態(tài)無法被改變;接受參數(shù)時,作用為在參數(shù)對象上部署接口?! ?/li>
- 手動改變對象的運(yùn)行狀態(tài)為已完成,從而立即觸發(fā)方法?! ?/li>
- 這個方法與正好相反,調(diào)用后將對象的運(yùn)行狀態(tài)變?yōu)橐咽?,從而立即觸發(fā)方法?! ?/li>
- .Deferred()生成一個deferred對象?! ?/li>
(2)deferred.done()指定操作成功時的回調(diào)函數(shù)
(3)deferred.fail()指定操作失敗時的回調(diào)函數(shù)
(4)deferred.promise()沒有參數(shù)時,返回一個新的deferred對象,該對象的運(yùn)行狀態(tài)無法被改變;接受參數(shù)時,作用為在參數(shù)對象上部署deferred接口?! ?/p>
(5)deferred.resolve()手動改變deferred對象的運(yùn)行狀態(tài)為"已完成",從而立即觸發(fā)done()方法。
(6)deferred.reject()這個方法與deferred.resolve()正好相反,調(diào)用后將deferred對象的運(yùn)行狀態(tài)變?yōu)?已失敗",從而立即觸發(fā)fail()方法。
(7).when() 為多個操作指定回調(diào)函數(shù)。
除了這些方法以外,deferred對象還有二個重要方法,上面的教程中沒有涉及到。
(8)deferred.then()
有時為了省事,可以把done()和fail()合在一起寫,這就是then()方法。
如果then()有兩個參數(shù),那么第一個參數(shù)是done()方法的回調(diào)函數(shù),第二個參數(shù)是fail()方法的回調(diào)方法。如果then()只有一個參數(shù),那么等同于done()。
(9)deferred.always()
這個方法也是用來指定回調(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>
另一個域下面一般處理程序,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é)果時回調(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ù)作為一個JavaScript對象來解析,并且把構(gòu)建好的對象作為結(jié)果返回。為了實(shí)現(xiàn)這個目的,他首先嘗試使用JSON.parse()。如果瀏覽器不支持,則使用一個函數(shù)來構(gòu)建。JSON數(shù)據(jù)是一種能很方便通過JavaScript解析的結(jié)構(gòu)化數(shù)據(jù)。如果獲取的數(shù)據(jù)文件存放在遠(yuǎn)程服務(wù)器上(域名不同,也就是跨域獲取數(shù)據(jù)),則需要使用jsonp類型。使用這種類型的話,會創(chuàng)建一個查詢字符串參數(shù) callback=? ,這個參數(shù)會加在請求的URL后面。服務(wù)器端應(yīng)當(dāng)在JSON數(shù)據(jù)前加上回調(diào)函數(shù)名,以便完成一個有效的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只需要將返回數(shù)據(jù)類型設(shè)置為jsonp就可以了,但是這種方法只支持get請求,不支持post請求;請求是同步的;服務(wù)器返回數(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有更好的錯誤處理。
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中,部署時還需要注意)。
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官方提供一個支持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等辦法。個人認(rèn)為CORS應(yīng)該才是未來主要的跨域選擇,其它的方法都只是hack。
四、彈出層
前面AJAX示例中添加功能如果放在一個彈出層中布局會更加緊湊一些,像登錄,提示信息經(jīng)常會需要彈出層。
常見的彈出層有:FancyBox,LightBox,colorBox,artDialog,BlockUI,Layer等,這里介紹騰訊開源的artDialog,輕量,實(shí)用。

artDialog是一個設(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)擊遮罩層自動關(guān)閉) quickClose: false, // css 文件路徑,留空則不會使用 js 自動加載樣式 // 注意:css 只允許加載一個 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
*/
/**
* 讓對話框聚焦(同時置頂)
* @name artDialog.prototype.focus
*/
/**
* 讓對話框失焦(同時置頂)
* @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)站的模板引擎就會生成一個標(biāo)準(zhǔn)的HTML文檔。前后端都有模板引擎,比如T4、FreeMarker、Velocity,這里主要講前端模板引擎:

上圖是常見的一些前端模板引擎,速度相對快的是artTemplate,與artDialog是同一個作者,當(dāng)然一個好的模板引擎不僅是速度還有很多方面都關(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)動","電影","購物"]
};
//用數(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)動 </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)
將返回一個渲染函數(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)動","<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>價格</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">
價格:
</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() {
/*動態(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("錯誤" + 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í)或者工作能帶來一定的幫助,同時也希望多多支持腳本之家!
- Ajax實(shí)現(xiàn)搜索引擎自動補(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-01
JS將數(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)容切換效果,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下2018-09-09
JS去除重復(fù)并統(tǒng)計(jì)數(shù)量的實(shí)現(xiàn)方法
js去除重復(fù)并統(tǒng)計(jì)數(shù)量方法,首先點(diǎn)擊按鈕觸發(fā)事件,然后用class選擇器,迭代要獲取的文本(這里最好用text()方法)加入到Array()集合里。具體操作方法,大家通過本文學(xué)習(xí)下吧2016-12-12
JS樹形結(jié)構(gòu)根據(jù)id獲取父級節(jié)點(diǎn)元素的示例代碼
這篇文章主要介紹了JS樹形結(jié)構(gòu)根據(jù)id獲取父級節(jié)點(diǎn)元素,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-05-05

