簡單實用的進度條載入組件loader.js

来源:http://www.cnblogs.com/lyzg/archive/2016/08/26/5808907.html
-Advertisement-
Play Games

本文提供一個簡單的方法實現一個流程的進度條載入效果,以便在頁面中可以通過它來更好地反饋耗時任務的完成進度。要實現這個功能,首先要考慮怎樣實現一個靜態的進度條效果,類似下麵這樣的: 這個倒是比較簡單,兩個div即可,bootstrap官方就提供有多種主題的進度條組件。如果自己要用,參照下別人的代碼,寫... ...


本文提供一個簡單的方法實現一個流程的進度條載入效果,以便在頁面中可以通過它來更好地反饋耗時任務的完成進度。要實現這個功能,首先要考慮怎樣實現一個靜態的進度條效果,類似下麵這樣的:

image

這個倒是比較簡單,兩個div即可,bootstrap官方就提供有多種主題的進度條組件。如果自己要用,參照下別人的代碼,寫成自己的風格即可,實際上也非常的好理解:

.progress {
    height: 20px;
    background-color: #f5f5f5;
    border-radius: 4px;
    box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
}

.progress-bar {
    float: left;
    width: 0;
    height: 100%;
    font-size: 12px;
    line-height: 20px;
    color: #fff;
    text-align: center;
    background-color: #337ab7;
    box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
    position: relative;
    border-radius: 4px;
}

第二步,就是該考慮下如何來計算進度。以資源載入為例,如果是客戶端,通常我們是有許可權去讀取資源實際大小的,所以在計算載入進度的時候,只要拿已載入的數據量除以要載入的總的數據量即可;但是在網頁端,我們沒有這個能力去拿到要載入的資源的大小,所以只能採用一個不那麼準確的方案,用已載入的資源個數除以總的資源個數。基於後面的計算方法,我們只需要在每個耗時任務完成的時刻,計算好已完成的任務進度,然後給進度條設置相應的寬度即可。

下麵我用定時器模擬了4個同時發起,但是需要不同時間才能完成的非同步任務來實現這一步的功能:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <link href="loader.css" rel="stylesheet">
</head>
<body>
<div id="loader" class="loader">
    <div class="progress">
        <div class="progress-bar progress-bar-striped">
            <div class="progress-value"></div>
        </div>
    </div>
</div>
</body>
<script src="jquery.js"></script>
<script>
    var $bar = $('#loader').find('.progress-bar');
    var $value = $bar.find('.progress-value');

    var Task = function (index, duration) {
        setTimeout(function () {
            var p = (index / 4 * 100).toFixed(0) + '%';
            $bar.css('width',p);
            $value.text(p);
            console.log('' + index + '個非同步任務執行完畢');
        }, duration);
    };

    //模擬四個同時發起的非同步任務
    var task1 = new Task(1, 1000);
    var task2 = new Task(2, 3000);
    var task3 = new Task(3, 5000);
    var task4 = new Task(4, 7000);
</script>
</html>

實際效果如下:

1

當到這一步的時候,其實就已經實現了一個基本的進度條載入功能了。但是上面的效果看起來其實體驗不是很好,要是這個進度條的各個進度值能夠連續地變化起來就好了,就像下麵這樣:

2

為了做到這一步,有的人可能會想到去利用transition,通過給進度條設置一個width .2s類似的transition,那麼當進度條寬度變化的自然就能看到進度條連續變化的效果了。這種方式有兩個問題:

1. 數字無法連續變化,因為數字從一個值變成另一個值無法通過transition進行過渡;

2. 看不到進度條載入到100%,因為當耗時任務完成進度為100%的時候,除了設置進度條的寬度為100%,一般還會有的邏輯都是隱藏或移除掉進度條,而進度條因為有transition的作用,從它原來的寬度過渡到100%還需要一定的時間,所以用戶看不到100%了。

不過這兩個都不是大問題,沒有進度數字的進度條也很常見;進度條不到100%就進入主功能場景的效果也很常見,而且這種效果有時還能給用戶一種錯覺,就是好像真的載入地很快。。

假如要糾結以上兩個問題,做一個有數字跟進度都滿足連續變化,並且一定要在進度條百分百顯示完載入效果之後才進入主場景的功能,該如何實現?就像下麵的這個類似效果:

3

在這個要求中,我覺得有兩個點需要註意:

一是當一個任務完成的時候,剩下的任務可能都還沒有完成,這個時候進度條就會進入等待狀態,要等到其它任務完成,有了新的進度之後才能看到下一次的載入效果;

二是進度條載入到100%時的回調控制,當任務完成進度為100%的時候,進度條可能還不到100%,等進度條從它當前值變到100%的時候,還需要時間,所以原來在任務完成進度為100%的時候添加的一些進入主場景之類的邏輯,就要換到進度條載入到100%的那個時刻去處理了。

綜合以上,我的思路是:

1. 把進度條的變化分成多段,因為每次耗時任務的完成,都會對應一個進度值,這些值大於0且小於等於100,以四個耗時任務為例,它們會把進度條分成:0-25, 25-50, 75-100三段;

2. 把第1步的分段抽象成一個進度條的載入任務,這個任務有兩個基本屬性:載入時間,變化區間。把這個任務做成一個動畫,在動畫的每次執行過程中,給外部提供一個回調,並傳入當前的進度值,以便設置進度條的寬度。當前的進度值可以根據動畫已經執行的時間,載入時間和變化區間來計算。變化區間對應的就是第1步裡面的百分比範圍。載入時間可以通過變化區間範圍 * 進度條載入1%需要的時間計算得到。也就是說要把動畫載入1%需要的時間作為一個常量。為了更方便一點,把動畫從0載入100%需要的時間作為一個常量更好控制一些。

3. 定義一個隊列,用來存放第2步抽象的載入任務。控制好隊列第一個任務的執行時機;每執行一個任務,就自動執行下一個。

4. 當任務進度是100%並且隊列里的最後一個任務完成的時候,通知外部進行回調。

基於這個思路,我的最終實現是(裡面有較詳細的註釋):

https://github.com/liuyunzhuge/blog/blob/master/progress_bar/loader.js

使用的方式可以參考(結合demo看上面的源碼,會更容易理解):

http://liuyunzhuge.github.io/blog/progress_bar/demo3.html

這個demo的實際效果就跟前面的那個gif一模一樣。

到此為止,我們就得到了一個看起來還比較實用的進度條載入效果控制的組件。不過它也不是沒有問題,它的問題在於:進度條載入完成的時間一定會大於我們在前面第2步設置的那個進度條一次性從0載入到100%需要的時間。也就是說這個做法會故意延遲整個耗時任務的過程。所以在實際使用的時候,前面說的那個常量不能定義太長了。

最後補充下,這個組件結合我之前寫的一個關於做圖片預載入的組件一起使用,可以做出更完美的圖片預載入效果,感興趣的可以嘗試一下。

希望本文的內容對大家的實際工作有所幫助,謝謝閱讀:)


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

-Advertisement-
Play Games
更多相關文章
  • 本文介紹了Java中的四種I/O模型,同步阻塞,同步非阻塞,多路復用,非同步阻塞。同時將NIO和BIO進行了對比,並詳細分析了基於NIO的Reactor模式,包括經典單線程模型以及多線程模式和多Reactor模式。 ...
  • 在Hibernate中有一種查詢語句是Criteria查詢(QBC查詢),今天呢 我們就一個個的詳細的跟大家一起探討Criteria語句的相關知識點 案例前的準備 案例一:查詢所有學生信息(Criteria) 經過以上語句我們可以看到的查詢結果如下: 案例二:查詢男生的信息(帶條件查詢)(Restr ...
  • 本文為原創文章,轉載請註明出處,謝謝 負載均衡 1、原理 服務端啟動創建臨時節點(下圖中servers下節點),臨時節點數據包含負載信息 客戶端啟動獲取伺服器列表,並根據負載去連接一個負載較輕的伺服器 服務端每次接收到客戶端的連接,添加自己的負載,客戶端斷開與自己的連接則減少自己的負載 2、架構圖 ...
  • 回到目錄 關於webapi我之前寫了一些文章,大家可以根據目錄去瀏覽,今天要說的是個怪問題,也是被我忽略的一個問題,當你的Url參數需要被Api自動解析成實體的屬性,實事上是要有條件的,不是所以屬性都可以被自動賦值的,下麵我們就來看看先決條件: 條件一:類屬性名稱必須和參數名稱相同 條件二:API參 ...
  • 一、設計模式 1、工廠模式 public class JiSuan { private int a; public int A { get { return a; } set { a = value; } } private int b; public int B { get { return b; ...
  • 一、類庫 引用別人寫的類 1、源代碼方法: 可以將直接寫好的.cs源代碼文件,添加進我的解決方案文件夾下,在解決方案資源管理器中, 項目上右鍵→添加→現有項,來添加此.cs源代碼文件的使用,需要引入相應的命名空間 2、類庫方法: 一個dll文件,就是一個類庫 它人新建一個類庫,在裡面編寫類和相應的方 ...
  • 靜態 1.普通成員 普通成員都是屬於對象的 用對象調用 2.靜態成員 靜態成員是屬於類的 用類名調用 stactic 靜態關鍵字 註:靜態方法裡面不能包含普通成員 普通方法裡面可以包含靜態成員 用處:1.為了簡便,連接資料庫的時候,造連接對象類,使用靜態屬性直接返回連接對象。 2.兩個類之間傳遞信息 ...
  • 一、封裝 目的:保護類,讓類更加安全。 做法:讓類裡面的成員變數變為私有(即訪問修飾符)的,做相應的方法或者屬性去間接的操作成員變數 ※訪問修飾符 private 私有的 只能在該類中訪問 protected 受保護的 只能在該類和它的子類中訪問 public 公有的 在任何地方都可以訪問 △封裝成 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...