您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關jQuery實現預加載圖片功能的方法的內容。小編覺得挺實用的,因此分享給大家做個參考。一起跟隨小編過來看看吧。
最近要用javascript做一個動畫功能,為了確保動畫在播放的時候能夠順利和平滑,我需要對所用到的圖片素材進行預加載
單圖片預加載
目前最常見的一種實現方式如下
function preloadImg(url) { var img = new Image(); img.src = url; if(img.complete) { //接下來可以使用圖片了 //do something here } else { img.onload = function() { //接下來可以使用圖片了 //do something here }; } }
首先實例化一個Image對象賦值給img,然后設置img.src為參數url指定的圖片地址,接著判斷img的complete屬性,如果本地有這張圖片的緩存,則該值為true,此時我們可以直接操作這張圖片,如果本地沒有緩存,則該值為false,此時我們需要監聽img的onload事件,把對img的操作放在onload的回調函數里面,經過測試,這種方案基本能夠兼容目前所有瀏覽器
多圖片預加載
很多場景下,單圖片預加載并不能滿足我們的需求,因為像動畫這種功能通常都會有很多的圖片素材,接下來我們就在原來單圖片預加載的基礎上來改進我們的函數
function preloadImg(list) { var imgs = arguments[1] || [], //用于存儲預加載好的圖片資源 fn = arguments.cal lee; if(list.length == 0) { return imgs; } var img = new Image(); img.src = list[0]; if(img.complete) { imgs.push(img); list.shift(); fn(list, imgs); } else { img.onload = function() { imgs.push(img); list.shift(); fn(list, imgs); }; } } var list = [......], //此處省略一萬個字符 imgs = preloadImg();
因為幀動畫可能需要保證每一幀動畫所用的圖片的順序,所以我在這段代碼中使用遞歸的方式,在上一張加載完成之后再去加載下一張圖片,每加載一張圖片,就把這張圖片資源存儲到imgs數組中,并且把這張圖片的地址從地址數組list中去掉,當list中已經沒有地址的時候跳出遞歸,并返回imgs數組
設想很美好,現實很殘酷,這段代碼有2個不能忍受的問題
首先,我很有可能拿不到最后返回的imgs數組,因為只要有圖片在本地沒有緩存,imgs的存儲操作都會放到onload的回調事件中,而事件監聽也屬于javascript中異步操作的一種,在綁定完onload事件的回調函數后,preloadImg函數就執行結束了,沒有任何返回值,外部imgs變量接收到的值為undefined,只有在所有圖片都有本地緩存的情況下,外部imgs變量才能順利拿到存儲了全部預加載圖片資源的數組
在加載完一張圖片之后才去加載下一張,整個預加載圖片的過程所需要的時間相對會比較長,用戶體驗會降低,而且本來異步操作具體速度快的特性,這樣的實現方式等于完全棄置了onload異步的這個特性
多圖片預加載(改進版)
這次我們直接把一個空數組作為參數傳進函數,圖片全部存儲到這個數組里面,下面是改進后的函數代碼(假設我們可以使用jQuery)
function preloadImg(list,imgs) { var def = $.Deferred(), len = list.length; $(list).each(function(i,e) { var img = new Image(); img.src = e; if(img.complete) { imgs[i] = img; len--; if(len == 0) { def.resolve(); } } else { img.onload = (function(j) { return function() { imgs[j] = img len--; if(len == 0) { def.resolve(); } }; })(i); img.onerror = function() { len--; console.log('fail to load image'); }; } }); return def.promise(); } var list = [......], //此處省略一萬個字符 imgs = []; $.when(preloadImg(list, imgs)).done( function() { //預加載結束 //do something here } );
在分別給每一個img綁定onload的回調函數時采用了閉包的方式,目的是為了保存住當前的遞增變量i,要是不這么做,結果將會是list地址中沒有本地緩存的圖片都存儲到imgs的最后一個元素上
這次每載入一張圖片,我們并沒有把這張圖片的地址從list數組中去掉,這樣后續需要使用list數組的數據時就能夠順利獲取到
在這次的代碼中,我們引入了jQuery的Deferred對象,這樣更方便我把握整個預加載圖片的過程
感謝各位的閱讀!關于jQuery實現預加載圖片功能的方法就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。