成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Javascript實現(xiàn)圖片的預加載功能

KavenFan / 1359人閱讀

摘要:本文同步自我得博客最近要用做一個動畫功能,為了確保動畫在播放的時候能夠順利和平滑,我需要對所用到的圖片素材進行預加載,下面跟大家分享一下我實現(xiàn)這個功能的過程單圖片預加載目前最常見的一種實現(xiàn)方式如下接下來可以使用圖片了接下來可以使用圖片了首先

本文同步自我得博客:http://www.joeray61.com

最近要用javascript做一個動畫功能,為了確保動畫在播放的時候能夠順利和平滑,我需要對所用到的圖片素材進行預加載,下面跟大家分享一下我實現(xiàn)這個功能的過程

單圖片預加載

目前最常見的一種實現(xiàn)方式如下

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,然后設(shè)置img.src為參數(shù)url指定的圖片地址,接著判斷imgcomplete屬性,如果本地有這張圖片的緩存,則該值為true,此時我們可以直接操作這張圖片,如果本地沒有緩存,則該值為false,此時我們需要監(jiān)聽imgonload事件,把對img的操作放在onload的回調(diào)函數(shù)里面,經(jīng)過測試,這種方案基本能夠兼容目前所有瀏覽器

多圖片預加載

很多場景下,單圖片預加載并不能滿足我們的需求,因為像動畫這種功能通常都會有很多的圖片素材,接下來我們就在原來單圖片預加載的基礎(chǔ)上來改進我們的函數(shù)

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數(shù)組中,并且把這張圖片的地址從地址數(shù)組list中去掉,當list中已經(jīng)沒有地址的時候跳出遞歸,并返回imgs數(shù)組
設(shè)想很美好,現(xiàn)實很殘酷,這段代碼有2個不能忍受的問題

首先,我很有可能拿不到最后返回的imgs數(shù)組,因為只要有圖片在本地沒有緩存,imgs的存儲操作都會放到onload的回調(diào)事件中,而事件監(jiān)聽也屬于javascript中異步操作的一種,在綁定完onload事件的回調(diào)函數(shù)后,preloadImg函數(shù)就執(zhí)行結(jié)束了,沒有任何返回值,外部imgs變量接收到的值為undefined,只有在所有圖片都有本地緩存的情況下,外部imgs變量才能順利拿到存儲了全部預加載圖片資源的數(shù)組

在加載完一張圖片之后才去加載下一張,整個預加載圖片的過程所需要的時間相對會比較長,用戶體驗會降低,而且本來異步操作具體速度快的特性,這樣的實現(xiàn)方式等于完全棄置了onload異步的這個特性

多圖片預加載(改進版)

這次我們直接把一個空數(shù)組作為參數(shù)傳進函數(shù),圖片全部存儲到這個數(shù)組里面,下面是改進后的函數(shù)代碼(假設(shè)我們可以使用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() {
        //預加載結(jié)束
        //do something here
    }
);

在分別給每一個img綁定onload的回調(diào)函數(shù)時采用了閉包的方式,目的是為了保存住當前的遞增變量i,要是不這么做,結(jié)果將會是list地址中沒有本地緩存的圖片都存儲到imgs的最后一個元素上
這次每載入一張圖片,我們并沒有把這張圖片的地址從list數(shù)組中去掉,這樣后續(xù)需要使用list數(shù)組的數(shù)據(jù)時就能夠順利獲取到
在這次的代碼中,我們引入了jQueryDeferred對象,這樣更方便我把握整個預加載圖片的過程,Deferred對象或者Promise對象的實現(xiàn)原理可以參看我的這篇文章

thx for reading, hope u enjoy

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/85310.html

相關(guān)文章

  • 圖片的預加載和懶加載

    摘要:圖片的預加載是提升用戶體驗而損失性能的一種做法,而懶加載的性能就比較好了,所以將兩個結(jié)合起來放到程序中是一種不錯的選擇。 最近在做H5滑頁時,遇到一些比較大的場景,動輒二十、三十頁,而圖片更是可恨的能達到上百個,所以就會導致場景在加載的時候遇到網(wǎng)速比較慢的時候,用戶等待的時間特別長,這樣的話,就有可能導致一部分的用戶沒有耐心,而丟失這部分用戶,于是就有了這里的圖片的預加載和懶加載,記個...

    SwordFly 評論0 收藏0
  • Link 標簽的預加載機制

    摘要:但這些加載器對于瀏覽器的加載優(yōu)先級隊列完全束手無策,這也使得他們不得不屈服于同樣的性能問題。 參考文章:https://developer.mozilla.org... 先簡單介紹下 link 標簽作用 你可以在頁面 元素內(nèi)部使用 標簽書寫一些聲明式的資源獲取請求 preload (預加載) 有些資源是在頁面加載完成后即刻需要的,對于這種即刻需要的資源,你可能希望在頁面加載的生命...

    付永剛 評論0 收藏0
  • 前端筆記(二) 對象的深淺拷貝,函數(shù)的防抖與節(jié)流,函數(shù)柯里化 ,圖片的預加載與懶加載

    摘要:對象是無法通過這種方式深拷貝。這就是函數(shù)防抖和節(jié)流要做的事情。函數(shù)防抖當觸發(fā)頻率過高時函數(shù)基本停止執(zhí)行而函數(shù)節(jié)流則是按照一定的頻率執(zhí)行事件。 對象的深淺拷貝 對象的深拷貝與淺拷貝的區(qū)別: 淺拷貝:僅僅復制對象的引用, 而不是對象本身。 深拷貝:把復制的對象所引用的全部對象都復制一遍 淺拷貝的實現(xiàn): var obj = { age : 18, person : { ...

    dongxiawu 評論0 收藏0
  • javascript 代理模式

    摘要:虛擬代理在開發(fā)中,我們往往將這個對象的實例化操作,放到函數(shù)內(nèi)部執(zhí)行,這樣的操作會減少不必要的實例化對象的開銷,造成資源的浪費。這種使用的情況我們將之成為虛擬代理。但是在中我們使用最多,也最常見的就是虛擬代理和緩存代理。 所謂的的代理模式就是為一個對象找一個替代對象,以便對原對象進行訪問。 使用代理的原因是我們不愿意或者不想對原對象進行直接操作,我們使用代理就是讓它幫原對象進行一系列的操...

    張利勇 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<