1. 程式人生 > >H5 progress js結合實現動態進度條顯示小記

H5 progress js結合實現動態進度條顯示小記

開通csdn好久了,出於工作原因,一直不能在網上記錄,但是終究覺得還是得留下些東西,所以開始整理筆記,調出可以記錄的描述一下,目的也是為了看到自己的成長,與大家共享。

今天這個是最近剛用過的,一直聽說H5的進度條標籤,一直也沒用過,這兩天剛好提出了需求,走起,小試一把,然後就記錄一下吧,其實還是蠻簡單的,重點就是建立好輪詢。

出於一些原因,有些地方我會用虛擬碼來標識。

第一步:就是在頁面裡寫好你想要進度展示的標籤,如果完全已知各種顯示樣式和情況,建議就直接寫在html裡,js控制顯隱就行,這樣比js插入dom要省些開銷。

<div id="loading" class="loading">
     <div id="pre">
         正在檢測:<progress id="progressPre" />
      </div>
      <div id="ready" class="hidden">
            開始下載:
           <progress id="progress" value="0" max="100" />
      </div>
      <div id="noWay" class="hidden">
                無法下載!
      </div>
</div>

第二步:在js裡利用ajax建立好輪詢機制,當然,可以用Comet和SSE,原理差不多,完全根據自己和實際的資源支援情況來定,我這邊就只能用ajax了。

因為要分別測試是否可下載,然後反饋下載進度或者無法下載,所以建立了兩次輪詢,一次負責輪詢是否可下載,一次負責進行下載進度反饋,這裡先把原理闡述,然後再貼程式碼。

第一次輪詢:將會像後臺詢問是否可下載,由於該步驟是通過查詢資料庫資料來實現,所以,一定一定不要輪詢太頻繁,否則頻繁連線資料庫,後果可能很嚴重(當然如果伺服器和資料庫很牛逼的,可以選擇性忽略,但是依然應該本著節約資源的原則開發,嗯是的),我這裡設定了3000ms輪詢一次,根據伺服器的反饋,這個頻率基本足夠,最多也就是2次就可以得到結果了。然而,這裡依然有個坑,就是用於輪詢反饋的欄位值,還是不要用0來標識了,因為貌似mysql在沒有值的時候(null),查詢返回前臺頁面的也是個0,我就被坑了,所有不管怎麼樣,儘量不要用0來標識。注意以上兩點,這部分就很簡單了, 寫好ajax,放入setInterval或者setTimeout鏈就可以了,在ajax的成功函式裡,根據返回值停止呼叫或者繼續呼叫。

第二次輪詢:如果可以下載,則進入第二次輪詢,查詢檔案下載進度;否則就沒有這一步了,直接反饋不可下載結束。這裡就說一下進度條<progress>了,有兩個屬性value和max,前者是當前完成的數值,後者是最大數值。所以不管你想進度什麼東西,都要確定這兩個資料,而且一定要匹配;如果是時間,就都用時間,如果是位元組,就都用位元組,否則會與實際情況不匹配。另外,如果你無法確定可以拿到這兩個資料,或者有一個無法拿到,那麼可能,就不能用了(這裡只是我針對這個標籤的結論,也許有大神會有其他方法)。一切如果無誤,則繼續ajax,建立輪詢,我這裡是下載檔案, 所有這次就只需要根據儲存檔案地址,不斷去輪詢檢視檔案大小,就知道當前檔案下載了多少,返回這個值,賦給value屬性,就可以在前臺看到進度條變化了。

虛擬碼如下:

第一次輪詢
var timer = setInterval/setTimeout(function a() {
	ajax({
        url:url,
        data:data,
        success:function(data){
            if(dataright){
               clearInterval(timer); //如果是setTimeout鏈,不需要這個。
               doOtherTing get max value;
                set max value to attr max;
               start downloadTimer;
            }else{
                //如果用的是setTimeout鏈,這裡繼續呼叫setTimout,否則不用寫else
                setTimout(a,3000)
            }
        }
    })
}, 3000)

第二次輪詢
var downloadtimer = setInterval/setTimeout(function a() {
	ajax({
        url:url,
        data:data,
        success:function(data){
            if(data < max){
                set data to attr value
               setTimout(a,3000)  //如果用的是setTimeout鏈,這裡繼續呼叫setTimout
            }else{
                clearInterval(timer); //如果是setTimeout鏈,不需要這個else。
             }
        }
    })
}, 1000)

如此一來,動態進度條就完成了。

總結一下要點:

1 . 寫好要顯示的progess標籤;

2.  根據實際需求建立輪詢機制,特別注意0值的問題,以及最大值和當前值的獲取問題;

3. 如果用定時器,建議setTimeout鏈,因為第一不需要手動清除,完事自己就停,第二,setInterval在js執行緒比較繁忙時,說白了,不能按既定時間來處理佇列的定時任務,有可能會跳過佇列中某一個已加入的任務;

4. 輪詢的次數一定要注意,根據伺服器和實際情況來確定,不可盲目頻繁進行,要為伺服器考慮哈;

5. 如果有大神有更好的方法,歡迎留言解惑,不勝感激