1. 程式人生 > 其它 >淺析 ProgressEvent 介面及其應用:上傳檔案進度事件

淺析 ProgressEvent 介面及其應用:上傳檔案進度事件

一、ProgressEvent 介紹

  ProgressEvent介面是測量如 HTTP 請求(一個XMLHttpRequest,或者一個 <img><audio><video><style><link> 等底層資源的載入)等底層流程進度的事件。

1、構造方法:ProgressEvent() (en-US):用給定的引數建立一個ProgressEvent 事件。

2、屬性:同時繼承它的父元素 Event 的屬性。

(1)ProgressEvent.lengthComputable只讀。是一個Boolean (en-US)

標誌,表示底層流程將需要完成的總工作量和已經完成的工作量是否可以計算。換句話說,它告訴我們進度是否可以被測量。

(2)ProgressEvent.loaded (en-US)只讀。是一個unsigned long long型別資料,表示底層流程已經執行的工作總量。可以用這個屬性和 ProgressEvent.total計算工作完成比例。當使用 HTTP 下載資源,它只表示內容本身的部分,不包括首部和其它開銷。

(3)ProgressEvent.total (en-US)只讀。是一個unsigned long long型別資料,表示正在執行的底層流程的工作總量。當使用 HTTP 下載資源,它只表示內容本身的部分,不包括首部和其它開銷。

3、方法:同時繼承它的父元素 Event 的方法。

  ProgressEvent.initProgressEvent() (en-US),使用被棄用的 Document.createEvent("ProgressEvent") 方法,來初始化一個已經建立好的ProgressEvent

4、下面的示例為一個新建的XMLHTTPRequest添加了一個 ProgressEvent,並使用它來顯示請求狀態。

var progressBar = document.getElementById("p"),
    client = new XMLHttpRequest()
client.open(
"GET", "magical-unicorns") client.onprogress = function(pe) { if(pe.lengthComputable) { progressBar.max = pe.total progressBar.value = pe.loaded } } client.onloadend = function(pe) { progressBar.value = pe.loaded } client.send()

二、進度事件(Progress Events)

  Progress Events 定義了客戶端與伺服器通訊有關的事件。這些事件最早其實只針對XHR操作,但目前也被其它API借鑑。有以下6個進度事件。

(1)loadstart:在接收到相應資料的第一個位元組時觸發。

(2)progress:在接收相應期間持續不斷觸發。

(3)error:在請求發生錯誤時觸發。

(4)abort:在因為呼叫abort()方法而終止連結時觸發。

(5)load:在接收到完整的相應資料時觸發。

(6)loadend:在通訊完成或者觸發error、abort或load事件後觸發。

  每個請求都從觸發 loadstart 事件開始,接下來是一或多個 progress 事件,然後觸發 error、abort 或 load 事件中的一個,最後以觸發 loadend 事件結束。

  這些事件大都很直觀,但其兩個事件有一些細節需要注意。

1、load 事件

  Firefox在實現XHR物件的某個版本時,曾致力於簡化非同步互動模型。最終,Firefox實現中引入了load事件,用以替代readystatechange事件。響應接收完畢後將觸發Load事件,因此也就沒有必要去檢查readyState屬性了。而onload事件處理程式會接收到一個event物件,其target屬性就指向XHR物件例項,因而可以訪問到XHR物件的所有方法和屬性。然而,並非所有瀏覽器都為這個事件實現了適當的事件物件。結果,開發人員還是要被迫使用XHR物件變數。

2、progress 事件

  progress 事件會在瀏覽器接收新資料期間週期性地觸發。而 onprogress 事件處理程式會接收到一個 event 物件,其 target 屬性是XHR物件,但包含著三個額外的屬性:lengthComputable、loaded 和 total。

  其中,lengthComputable是一個表示進度資訊是否可用的布林值,loaded表示已經接收的位元組數,total 表示根據 Content-Length 響應頭部確定的預期位元組數。

  有了這些資訊,我們就可以為使用者建立一個進度指示器了。下面展示了為使用者建立進度指示器的一個示例。

var xhr = createXHR();
xhr.onload =function(){
    if((xhr.status >=200&& xhr.status <300)|| xhr.status ==304){
        alert(xhr.responseText);
    }else{
        alert("Request was unsuccessful: "+ xhr.status);
    }
};
xhr.onprogress =function(event){ var divStatus = document.getElementById("status"); if(event.lengthComputable){ divStatus.innerHTML ="Recived"+event.loaded +" of "+event.total +" bytes"; }} xhr.open("get","altevents.php",true); xhr.send(null);

  為確保正常執行,必須在呼叫 open() 方法之前新增 onprogress 事件處理程式。在前面的例子中,每次觸發 progress 事件,都會以新的狀態資訊更新HTML元素的內容。如果響應頭部中包含Content-Length欄位,那麼也可以利用此資訊來計算從響應中已經接收到的資料的百分比。

// 當請求型別為post時需要監聽xhr.upload。
// post 一般用來獲取上傳進度、get 用來獲取下載進度
xhr.upload.onprogress =function(e){
  if(e.lengthComputable){ console.log(e.loaded / e.total *100)
  }
}