本文分析的問題,比較奇葩。可能大家在一般的項目中都用不到。所以首先要先瞭解這個應用情境。反正我分析了之後才發現jquery全域$.ajax竟然可以這樣用!
1、背景
在頁面中使用ajax請求進行非同步作業這個現在比較常用,我們會在ajax開始時候加個進度顯示,在complete之後隱藏即可。但是要是頁面內有多個ajax請求,我們怎麼處理這個進度那?單個單個處理肯定會很麻煩,比如你不知道所有頁面的ajax什麼時候都處理完成,需要很具體的寫代碼才行。
單個ajax請求:
代碼如下 |
複製代碼 |
function GetEditData() { if (ID == null || ID == 0) { return; } //開始啟動進度條 $("#btnnext").html("修改"); $.ajax({ type: "post", url: ajaxUrl, data: { activeid: ID, Operate: "view" }, success: function (data, textStatus) { if (data != null) { $("#txttitle").val(data.title); } else { alert("載入資料失敗:" ); return; } }, complete: function (XMLHttpRequest, textStatus) { //完成了。去除進度條 }, error: function (e) { alert("載入資料失敗。"); return; } }); }
|
又或者這個情況:提交表單的所有活動ajax請求失敗時,並觸發錯誤事件.如何停止在jQuery中所有活動的ajax請求,而不trigerring錯誤事件?
2、分析
這裡就用到了ajax的全域變數。具體可以到這裡看看[Jquery $.ajax請求詳解及ajax全域變數分析]。這裡指說明一下我們用的全域變數。
jquery $.ajax有一些全域變數:
.ajaxComplete() 當 Ajax 請求完成時註冊要調用的處理常式。這是一個 Ajax 事件。
.ajaxError() 當 Ajax 請求完成且出現錯誤時註冊要調用的處理常式。這是一個 Ajax 事件。
.ajaxSend() 在 Ajax 請求發送之前顯示一條訊息。
jQuery.ajaxSetup() 設定將來的 Ajax 請求的預設值。
.ajaxStart() 當首個 Ajax 請求完成開始時註冊要調用的處理常式。這是一個 Ajax 事件。
.ajaxStop() 當所有 Ajax 請求完成時註冊要調用的處理常式。這是一個 Ajax 事件。
.ajaxSuccess() 當 Ajax 請求成功完成時顯示一條訊息。
我們通過這些全域變數就能夠儲存每次ajax請求,並在每個ajax請求處理完成後,清理這個緩衝。
首先我們定義個實體儲存每次ajax請求的資料:
代碼如下 |
複製代碼 |
function AjaxModel(id, status) { this.id = id; this.status = status; return this; }
|
然後在ajax的處理事件中加上邏輯:
代碼如下 |
複製代碼 |
// 添加ajax全域事件處理。 $(document).ajaxStart(function (a, b, c) { }).ajaxSend(function (e, jqXHR, options) { sendcount++; jqXHR.id = sendcount; var model = new AjaxModel(jqXHR, 0); if (xhrPool.length == 0) { // timer = setInterval("CheckIsAjaxLoadok()", 10);//1000為1秒鐘 $.fn.jqLoading({ height: 100, width: 240, text: "正在載入中,請耐心等待...." }); } xhrPool.push(model); }).ajaxError(function (e, xhr, opts) { }).ajaxSuccess(function (e, xhr, opts) { }).ajaxComplete(function (e, jqXHR, options) { $.each(xhrPool, function (key, val) { if (val.id.id== jqXHR.id) { val.status = 1; } }); var xhrPooltemp = $.grep(xhrPool, function (x) { return x.status==0 }); if (xhrPooltemp.length == 0) { $.fn.jqLoading("destroy"); } }).ajaxStop(function () { });
|
這裡面最主要的是將ajax的XMLHttpRequest 對象儲存到我們定義的array數組中。這裡需要注意:
每次XMLHttpRequest 對象jquery會儲存,在ajax 完成後銷毀。所以這裡我們就可以用判斷每個ajax是否完成。XMLHttpRequest 對象是沒有id這個屬性的,我們可以自己給他加上這個屬性。
代碼如下 |
複製代碼 |
.ajaxSend(function (e, jqXHR, options) { sendcount++; jqXHR.id = sendcount; var model = new AjaxModel(jqXHR, 0); if (xhrPool.length == 0) { // timer = setInterval("CheckIsAjaxLoadok()", 10);//1000為1秒鐘 $.fn.jqLoading({ height: 100, width: 240, text: "正在載入中,請耐心等待...." }); } xhrPool.push(model); }) |
jqXHR.id = sendcount;給這個XMLHttpRequest對象加上了id,按照發起請求的順序給他一個id。
在complete函數中,我們找到這個對應id的XMLHttpRequest對象,設定它完成了。
這樣這個頁面的所有ajax請求,我們都能夠管理起來。剩下的能做的事情就很多了。可以判斷每個ajax請求是否完成,中止所有的ajax請求,在全部ajax完成後取消遮罩層等等。