正所謂金三銀四五吃土,所以這些天幾個前端技術羣討論最多的話題就是面試題了。某日羣內討論一道面試題:「前端如何實現大量圖片預加載以及預加載進度動畫進度條顯示?」javascript
恰巧本人之前jquery、zepto一把梭快樂切圖的時候,寫過很多形式的圖片預加載動畫。對於圖片預加載的原理稍微瞭解接觸過那麼一點點,這裏獻醜一番簡單寫一個預加載案例,做爲19年第一篇博(段)客(子)快樂一哈。css
既然是利用image對象搞事情,那確定少不了大量的img圖片。所以我從名字中包含刺激二字的網站上面扒了很多各位帶妹司機熱血沸騰的圖片,沒錯就是騰訊刺激戰場--各類武器圖片。html
emmm,不皮了。咱們直接進入主題內容,JavaScript當中的image對象。關於Image對象的介紹MDN上面寫的, 當new Image()
的時候會生成一個HTMLImageElement
.前端
HTMLImageElement
這是什麼?和咱們熟悉的HTMLElement
這個節點有什麼不一樣呢?順着上面的連接提示,咱們繼續順藤摸瓜,最後發現HTMLImageElement
屬於HTMLElement
孩子。java
既然繼承了HTMLElement
特性,同理body元素有一個onload
屬性,那麼同理new Image獲得對象也一樣擁有onload
屬性。node
那麼就讓咱們利用,new Image()
來搞事情jquery
日常咱們在接觸img
元素的時候,都知道書寫img
標籤的時候,必然少不了添加src
屬性,否則圖片加載不出來。因此咱們第一步就是批量設置這些須要預加載的圖片路徑地址,這樣onload
才能發揮其做用。webpack
這裏的圖片太多了,一張一張的手寫,未免太麻煩了。爲了節省時間,這裏我拿出一年多之前剛剛學Node的時候寫的一個js腳本,來批量獲取圖片名稱生成數組對象列表。git
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就加載,並不能很好看的預加載過程。
因此爲了小夥伴們可以更加直觀的看到預加載的過程,這裏咱們決定進行真實環境模擬:
// loadEl.innerHTML = '正在加載中'; loadEl.innerHTML = `正在加載中${Math.round(count / length * 100)}%`;
好了!以上就是鄙人對於前端圖片預加載一點簡單理解與複習了,主要回顧一些image()基本屬性點。
固然,前端圖片預加載方法也並不止這麼一種,方法仍是有好幾種。因此後續使用何種方法就各位小夥伴本身了。這裏有一篇大佬翻譯的文章就提到三種前端預加載的方法,但願能夠給你們一個參考。
這篇文章中的第二個方法,就是本文采用的方法。因此但願各位大佬待會點進看完以後,不要出來打我。畢竟我不是大佬代碼水平,我只是一個快樂前端段子手。
傳送門地址:譯:利用CSS、JavaScript及Ajax實現圖片預加載的三大方法
考慮新年第一篇文章,吹水過多不在狀態,因此良(很)心(皮)的我,決定錦上添花額外寫一個快樂loading動畫做爲給我大哥賠罪。
這裏就是百分比數字,分割成兩位,而後經過數字的不一樣,改變圖片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上閱覽。
原創文章,文筆有限,才疏學淺,文中如有不正之處,再次再次再次歡迎各位啪啪的打臉賜教。(有句話說的好,重要的詞得說三遍。)
我是車大棒!我爲我本身帶眼了!