快樂前端-圖片預加載

前言

正所謂金三銀四五吃土,所以這些天幾個前端技術羣討論最多的話題就是面試題了。某日羣內討論一道面試題:「前端如何實現大量圖片預加載以及預加載進度動畫進度條顯示?」javascript

恰巧本人之前jquery、zepto一把梭快樂切圖的時候,寫過很多形式的圖片預加載動畫。對於圖片預加載的原理稍微瞭解接觸過那麼一點點,這裏獻醜一番簡單寫一個預加載案例,做爲19年第一篇博(段)客(子)快樂一哈。css

你離捱打只差一點點.png

1、利用image對象搞事情

既然是利用image對象搞事情,那確定少不了大量的img圖片。所以我從名字中包含刺激二字的網站上面扒了很多各位帶妹司機熱血沸騰的圖片,沒錯就是騰訊刺激戰場--各類武器圖片。html

武器截圖.png

emmm,不皮了。咱們直接進入主題內容,JavaScript當中的image對象。關於Image對象的介紹MDN上面寫的, 當new Image()的時候會生成一個HTMLImageElement.前端

Image對象執行.png

HTMLImageElement這是什麼?和咱們熟悉的HTMLElement這個節點有什麼不一樣呢?順着上面的連接提示,咱們繼續順藤摸瓜,最後發現HTMLImageElement 屬於HTMLElement孩子。java

HTMLImageElement.png

既然繼承了HTMLElement特性,同理body元素有一個onload屬性,那麼同理new Image獲得對象也一樣擁有onload屬性。node

那麼就讓咱們利用,new Image()來搞事情jquery

2、預加載和預加載動畫實現

一、批量設置圖片路徑

日常咱們在接觸img元素的時候,都知道書寫img標籤的時候,必然少不了添加src屬性,否則圖片加載不出來。因此咱們第一步就是批量設置這些須要預加載的圖片路徑地址,這樣onload才能發揮其做用。webpack

這裏的圖片太多了,一張一張的手寫,未免太麻煩了。爲了節省時間,這裏我拿出一年多之前剛剛學Node的時候寫的一個js腳本,來批量獲取圖片名稱生成數組對象列表。git

node生成的數組.png

PS:這裏就不掛載nodefs腳本代碼,文末我將會這個小demo地址附上(包括nodefs.js),感興趣的小夥伴能夠點擊訪問。github

二、預加載圖片效果測試

由於我此前是用的webpack工具構建的項目,支持模塊引入imglist.js. 這裏我爲了demo演示,所以咱們就直接將這個數組對象複製粘貼到演示HTML當中。

<body>
    <h1 class="loading"></h1>
</body>
</html>
<script>
    let imglist = [{name: 'AKM', url: 'AKM.png'},{name: 'AUG', url: 'AUG.png'},{name: 'AWM', url: 'AWM.png'},{name: 'crossbow', url: 'crossbow.png'},{name: 'Crowbar', url: 'Crowbar.png'},{name: 'DP-28', url: 'DP-28.png'},{name: 'G36C', url: 'G36C.png'},{name: 'Groza', url: 'Groza.png'},{name: 'Kar98k', url: 'Kar98k.png'},{name: 'M16A4', url: 'M16A4.png'},{name: 'M24', url: 'M24.png'},{name: 'M249', url: 'M249.png'},{name: 'M416', url: 'M416.png'},{name: 'M762', url: 'M762.png'},{name: 'Machete', url: 'Machete.png'},{name: 'Micro-UZI', url: 'Micro-UZI.png'},{name: 'Mini14', url: 'Mini14.png'},{name: 'Mk14', url: 'Mk14.png'},{name: 'MK47', url: 'MK47.png'},{name: 'P18C', url: 'P18C.png'},{name: 'p1911', url: 'p1911.png'},{name: 'P92', url: 'P92.png'},{name: 'Pan', url: 'Pan.png'},{name: 'QBU', url: 'QBU.png'},{name: 'QBZ', url: 'QBZ.png'},{name: 'R1895', url: 'R1895.png'},{name: 'R45', url: 'R45.png'},{name: 'S12K', url: 'S12K.png'},{name: 'S1897', url: 'S1897.png'},{name: 'S686', url: 'S686.png'},{name: 'Sawed-off', url: 'Sawed-off.png'},{name: 'SCAR-L', url: 'SCAR-L.png'},{name: 'Scorpion', url: 'Scorpion.png'},{name: 'Sickle', url: 'Sickle.png'},{name: 'Signal', url: 'Signal.png'},{name: 'SKS', url: 'SKS.png'},{name: 'SLR', url: 'SLR.png'},{name: 'Thomson', url: 'Thomson.png'},{name: 'UMP9', url: 'UMP9.png'},{name: 'Vector', url: 'Vector.png'},{name: 'VSS', url: 'VSS.png'},{name: 'win94', url: 'win94.png'}];
    let length = imglist.length;
    let images = new Array(); // 定義一個數組容器,用來存儲預加載完成的圖片
    let loadEl = document.querySelector('.loading');
    function preload () {
        let count = 0; // 計算器,計算加載了多少圖片
        for (let i = 0; i < length; i++) {
            images[i] = new Image();
            images[i].src = `./imgs/${imglist[i].url}`; 
            // 谷歌瀏覽器高版本支持大部分ES6,因此這裏就不用字符串拼接了。
            images[i].onload = function () {
                count++;
                if (count === length) {
                    loadEl.innerHTML = '加載完成';
                } else {
                    loadEl.innerHTML = '正在加載中';
                }
            }
        }
    }
    preload();
</script>

打開頁面從新刷新一下,在控制檯NetWork能夠將圖片所有加載出來。emmm,可是因爲本地加載速度太快了,一會兒就加載完成。經過下面截圖能夠看到,加載時間不到1s就加載,並不能很好看的預加載過程。

加載太快.png

三、預加載圖片真實環境模擬

因此爲了小夥伴們可以更加直觀的看到預加載的過程,這裏咱們決定進行真實環境模擬:

①這裏我利用vscode自帶的插件,生成一個本地服務器。

vscode-live.png

②而後在切換到瀏覽器控制檯下NetWork,將網速調整爲Fast3G

Fast3G.png

③ 而後將以前加載中的代碼修改,成百分比顯示。

// loadEl.innerHTML = '正在加載中';
loadEl.innerHTML = `正在加載中${Math.round(count / length * 100)}%`;

最終效果以下:

GIF-1552205242262.gif

3、小結

好了!以上就是鄙人對於前端圖片預加載一點簡單理解與複習了,主要回顧一些image()基本屬性點。

固然,前端圖片預加載方法也並不止這麼一種,方法仍是有好幾種。因此後續使用何種方法就各位小夥伴本身了。這裏有一篇大佬翻譯的文章就提到三種前端預加載的方法,但願能夠給你們一個參考。

這篇文章中的第二個方法,就是本文采用的方法。因此但願各位大佬待會點進看完以後,不要出來打我。畢竟我不是大佬代碼水平,我只是一個快樂前端段子手。

傳送門地址:譯:利用CSS、JavaScript及Ajax實現圖片預加載的三大方法

我毫不道歉.png

考慮新年第一篇文章,吹水過多不在狀態,因此良(很)心(皮)的我,決定錦上添花額外寫一個快樂loading動畫做爲給我大哥賠罪。

快樂loading小動畫

CSS3預加載動畫.gif

這裏就是百分比數字,分割成兩位,而後經過數字的不一樣,改變圖片background-position屬性,來完成loading預加載動畫。

images[i].onload = function () {
    count++;
    if (count === length) {
        loadStart.style.display = 'none';
            loadEnd.style.display = 'block';
            loadEnd.onclick = function () {
                alert('恭喜學習圖片預加載!');
            }
     } else {
       // loadEl.innerHTML = '正在加載中';
       // loadEl.innerHTML = `正在加載中${Math.round(count / length * 100)}%`;
       let text = Math.round(count / length * 100);
       let text1 = parseInt(text / 10);
       let text2 = parseInt(text % 10);
       console.log(text1, text2);
       num1.style.backgroundPositionX = `${-47 + text1 * -60}px`
       num2.style.backgroundPositionX = `${-47 + text2 * -60}px`
      }
  }

因此對完整blogDemo代碼感興趣的,能夠從本人github上閱覽。

源碼demo傳送門地址

原創文章,文筆有限,才疏學淺,文中如有不正之處,再次再次再次歡迎各位啪啪的打臉賜教。(有句話說的好,重要的詞得說三遍。)

我是車大棒!我爲我本身帶眼了!

皮皮蝦咱們走.png

相關文章
相關標籤/搜索