JavaScript學習總結(一)——延遲對象、跨域、模板引擎、彈出層、AJAX示例

来源:http://www.cnblogs.com/best/archive/2016/12/19/6196202.html
-Advertisement-
Play Games

一、AJAX示例 AJAX全稱為“Asynchronous JavaScript And XML”(非同步JavaScript和XML) 是指一種創建互動式網頁應用的開發技術、改善用戶體驗,實現無刷新效果。 1.1、優點 不需要插件支持 優秀的用戶體驗 提高Web程式的性能 減輕伺服器和帶寬的負擔 1 ...


一、AJAX示例

AJAX全稱為“Asynchronous JavaScript And XML”(非同步JavaScript和XML) 是指一種創建互動式網頁應用的開發技術、改善用戶體驗,實現無刷新效果。

1.1、優點

不需要插件支持

優秀的用戶體驗

提高Web程式的性能

減輕伺服器和帶寬的負擔

1.2、缺點

瀏覽器對XMLHttpRequest對象的支持度不足,幾乎所有瀏覽器現在都支持

破壞瀏覽器“前進”、“後退”按鈕的正常功能,可以通過簡單的插件彌補

對搜索引擎的支持不足

1.3、jQuery AJAX示例

在HTML5中對原生的AJAX核心對象XMLHttpRequest進行升級,也就是XHR2,功能更加強大。 

jQuery對AJAX封裝的非常好,這裡以簡單的商品管理為示例使用jQuery完成AJAX應用。

Product.java bean:

package com.gomall.bean;

/***
 * 產品
 * 
 * @author Administrator
 *
 */
public class Product {
    /** 編號 */
    private int id;
    /** 名稱 */
    private String name;
    /** 價格 */
    private double price;
    /** 圖片 */
    private String picture;
    /** 詳細 */
    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);

    /**根據編號獲得產品對象*/
    Product findById(int id);

    /**根據編號獲得產品對象
     * @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/全網通華為超級閃充技術雙後攝設計" + random.nextInt(999), random.nextDouble() * 1000,
                    "pic(" + i + ").jpg", "產品詳細");
            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 {
        /*模擬網路延時*/
        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")) {
            /**向響應的頭部中添加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")){
            /**向響應的頭部中添加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")){
            /**向響應的頭部中添加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);
    }
}

運行結果:

刪除:

二、延遲對象(Deferred)

deferred對象就是jQuery1.5版以後新增加的回調函數解決方案。

2.1、回調函數

先看一個示例:

首先,為什麼要使用Deferred?

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>回調</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"}

運行結果:

因為AJAX是非同步執行的,類似高級語言中的多線程,當發起ajax請求時會有網路延遲,而代碼並沒有在$.get的位置被阻塞,alert先執行,但數據並沒有從遠程獲取到,所以結果是undefined。

其實初學者經常會犯這種錯誤,如:

            function getStudentById(id){
                $.get("students.do",{"id":id},function(stu){
                    return stu;
                },"json");
            }

上面的代碼是有問題的,原因如前面的示例是一樣的。怎麼解決,如果你認為是非同步帶來的問題,當然通過同步是可以解決的,如:

            $.ajax({
                type:"get",
                url:"student.json",
                async:false,  /*非非同步,同步*/
                success:function(data){
                    student=data;
                }
            });

結果:

如果將所有的ajax請求修改為同步的,則ajax的好處就大打折扣了,如果即要非同步又要解決上面的問題,可以使用回調方法。

示例:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>回調</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是一個當ajax請求成功時的回調方法*/
            function getStudent(callback) {
                $.get("student.json", function(data) {
                    callback(data);
                }, "json");
            }
            
            /*調用getStudent函數,傳入參數,參數也是一個函數*/
            getStudent(function(stu){
                alert(stu.id);
            });
            
            /*把一個方法作為參數傳遞給另一個方法可以認為是委托,如C++中的函數指針類似*/
            getStudent(function(stu){
                alert(stu.name);
            });
        </script>
    </body>
</html>

結果:

 

從這裡看回調很完美,其實不然,實際開發中要複雜得多,如當第一個ajax請求完成才可以完成第二個,當第二個完成才可以完成第三個,可能最一個請求要等前面的所有請求都成功時才允許執行或才有條件執行,如

使用ajax編輯用戶信息,先載入用戶對象,再載入省,載入市,加縣,可能代碼會這樣寫:

            $.get("url1",function(){
                $.get("url2",function(){
                    $.get("url3",function(){
                      ...
                   });
                });
            });

當回調越來越多,嵌套越深,代碼可讀性就會越來越差。如果註冊了多個回調,那更是一場噩夢,幸好從jQuery1.5開始出現了延遲對象(deferred),可以解決這個問題。

2.2、deferred.done

$.ajax()操作完成後,如果使用的是低於1.5.0版本的jQuery,返回的是XHR對象,你沒法進行鏈式操作;如果高於1.5版,返回的是deferred對象,可以進行鏈式操作。

當延遲成功時調用一個函數或者數組函數,功能與原success類似。

語法:deferred.done(doneCallbacks[,doneCallbacks]) 

返回值:Deferred Object

該參數可以是一個函數或一個函數的數組。當延遲成功時,doneCallbacks被調用。回調執行是依照他們添加的順序。一旦deferred.done()返回延遲對象,延遲對象的其它方法也可以鏈接到了這裡,包括增加.done()方法。當延遲解決,doneCallbacks執行使用參數提供給 resolveresolveWith方法依照添加的順序調用。

示例代碼:

<!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>

運行結果:

2.3、deferred.fail

語法:deferred.fail(failCallbacks[,failCallbacks])

返回值:Deferred Object

當延遲失敗時調用一個函數或者數組函數,功能與原回調方法error類似。

該參數可以是一個函數或一個函數的數組。當延遲失敗時,doneCallbacks被調用。回調執行是依照他們添加的順序。一旦deferred.fail()返回延遲對象,延遲對象的其它方法也可以鏈接到了這裡,包括增加.done()方法。當延遲解決,doneCallbacks執行使用參數提供給 resolveresolveWith方法依照添加的順序調用。

示例:

<!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>

運行結果:

2.4、deferred.always

語法:deferred.always(alwaysCallbacks,[alwaysCallbacks])

返回值:Deferred Object

當遞延對象是解決(成功,resolved)或拒絕(失敗,rejected)時被調用添加處理程式,與回調方法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執行完成,完成狀態:"+textStatus);
            });
        </script>
    </body>
</html>

運行結果

成功時:

 

失敗時:

2.5、deferred.then

deferred.then(doneFilter [, failFilter ] [, progressFilter ])

添加處理程式被調用時,遞延對象得到解決或者拒絕,一次指定多個事件。

所有三個參數(包括progressCallbacks ,在jQuery的1.7 )可以是一個單獨的函數或一個函數的數組。 其中一個參數,也可以為空,如果沒有該類型的回調是需要的。或者,使用.done()或.fail()僅設置doneCallbacks或failCallbacks。當遞延解決,doneCallbacks被調用。若遞延代替拒絕,failCallbacks被調用。回調按他們添加的順序執行。一旦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>

結果:

2.6、應用延遲對象

前面的示例中我們都是使用jQuery ajax返回的deferred對象,其實我們也可以在自定義的代碼中使用deferred對象,恰當的使用deferred對象或以優雅的解決不少問題。

示例:

<!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創建一個延遲對象
                var def=$.Deferred();
                setTimeout(function(){
                    //隨機產生一個整數,如果是偶數
                    var n=Math.round(Math.random()*100);
                    if(n%2==0)
                    {
                        console.log("一個耗時的操作終於完成了,n="+n);
                        def.resolve();   //任務成功完成
                    }else{
                        console.log("一個耗時的操作失敗,n="+n);
                        def.reject();  //拒絕,失敗
                    }
                },3000);
                 //返回延遲對象,防止中間修改
                return def.promise();
            }
            
            /*當方法myTask執行完成後,添加回調方法*/
            $.when(myTask()).done(function(){
                console.log("執行成功");
            }).fail(function	   

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 微盤系統,微盤搭建,微盤源碼,微交易系統搭建,微交易源碼,微交易系統, 本公司微交易系統,是基於微信端開發的交易平臺。平臺適用於貴金屬、外匯、原油、期貨…等多個交易品種的投資者,並對接多個移動支付介面,輕鬆解決出入金問題。程式說明:2017新版微交易系統建設,採用新浪數據介面,非常穩定,直接運營版本 ...
  • 閱讀目錄 架構的定義 如何開始設計一個架構 一個好架構的特點 做架構中的誤區 結語 一、架構的定義 所謂一千個架構師中有一千種“最好的架構”模式。 “架構”是我們這行業種一個很常見的詞,表明其必然也是經歷了很長的歲月打磨所形成的一個詞。架構的這個詞出現的意義是什麼?為瞭解決什麼問題?只有把這2個問題 ...
  • 引子 前幾天看到微信後臺團隊分享了TLS相關文章,正好gRPC里TLS數據加密是很重要的一塊,於是整理出了這篇文章。 在gRPC里,如果僅僅是用來做後端微服務,可以考慮不加密。本文太長,先給個大綱。 1. HTTPS,HTTP/2介紹 2. TLS加密原理、實現庫 3. HTTP/2協議協商機制 4 ...
  • 一、Angular特點: 1、雙向數據綁定,主打賣點 2、MVVM 模型,把視圖和邏輯分開 3、依賴註入 個人感覺,在Angular中,視圖對應 HTML 模板,視圖邏輯對應directive 和 controller。 二、模塊 Angular 中通過模塊來管理命名空間,可以通過不同的模塊來隔離不 ...
  • 本文轉載自 http://www.mynawang.com/ 相關代碼可訪問 https://github.com/mynawang/Design-Pattern-Learning 什麼是設計模式 設計模式(Design pattern)是一套被反覆使用、多數人知曉的、經過分類編目的、代碼設計經驗的 ...
  • <html> ...
  • 簡介 "transformjs" 在非react領域用得風生水起,那麼react技術棧的同學能用上嗎?答案是可以的。junexie童鞋已經造了個 "react版本" 。 動畫實現方式 傳統 web 動畫的兩種方式 : 1. 純粹的CSS3 :如:transition/animation+transf ...
  • 基本上每個項目都需要用到模態框組件,由於在最近的項目中,alert組件和confirm是兩套完全不一樣的設計,所以我將他們分成了兩個組件,本文主要討論的是confirm組件的實現。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...