1. 程式人生 > >圖片預載入的實現

圖片預載入的實現

圖片預載入說白了就是將所有所需的圖片提前請求載入到本地,這樣後面在需要用到時就直接從快取取圖片 。圖片預載入的原理很簡單:new Image(),然後使用onload方法回撥預載入完成事件,當瀏覽器把圖片下載到本地後,之後同樣的src就直接使用快取。

無序載入

// 所有的圖片(要是網路太好,自己加圖片吧)
const imgs = [
    "http://op2clp53n.bkt.clouddn.com/20161104122758_cap-hpi.jpg",
    "http://op2clp53n.bkt.clouddn.com/500414621%20%281%29.jpg",
    "http://op2clp53n.bkt.clouddn.com/cover_bg.png",
    "http://img.aotu.io/mamboer/post-aotu.jpg",
    "http://misc.aotu.io/o2/img/books/books-cover.jpg",
    "http://img.aotu.io/Yettyzyt/cover.png",
    "http://img.aotu.io/wengeek/responsive-image.png",
    "https://gw.alicdn.com/tfs/TB1_6wnRXXXXXbwXFXXXXXXXXXX-900-500.jpg",
    "http://op2clp53n.bkt.clouddn.com/_138.jpg",
    "http://op2clp53n.bkt.clouddn.com/0_ocs_fin_cov_1.jpg",
    "http://op2clp53n.bkt.clouddn.com/2voyage.jpg",
    "http://op2clp53n.bkt.clouddn.com/boa_illustrations_master_fb_1200x628-12.jpg",
    "http://op2clp53n.bkt.clouddn.com/building_science_bulletin_cover_2__1x.jpg",
    "http://op2clp53n.bkt.clouddn.com/building-science-bulletin-cover_1x.jpg",
    "http://op2clp53n.bkt.clouddn.com/chemistry4_1x.png",
    "http://op2clp53n.bkt.clouddn.com/first_colony_dribbble_copy.jpg"
];
let len = imgs.length;

/**
 * 遍歷imgs陣列,將所有圖片加載出來
 * 可以通過控制檯檢視網路請求,會發現所有圖片均已載入
 */
for (let i = 0; i < len; i++) {
    let imgObj = new Image(); // 建立圖片物件
    imgObj.src = imgs[i];

    imgObj.addEventListener('load', function () { // 這裡沒有考慮error,實際上要考慮
        console.log('imgs' + i + '載入完畢');
    }, false);
}

有序載入

// 所有的圖片(要是網路太好,自己加圖片吧)
const imgs = [
    "http://op2clp53n.bkt.clouddn.com/20161104122758_cap-hpi.jpg",
    "http://op2clp53n.bkt.clouddn.com/500414621%20%281%29.jpg",
    "http://op2clp53n.bkt.clouddn.com/cover_bg.png",
    "http://img.aotu.io/mamboer/post-aotu.jpg",
    "http://misc.aotu.io/o2/img/books/books-cover.jpg",
    "http://img.aotu.io/Yettyzyt/cover.png",
    "http://img.aotu.io/wengeek/responsive-image.png",
    "https://gw.alicdn.com/tfs/TB1_6wnRXXXXXbwXFXXXXXXXXXX-900-500.jpg",
    "http://op2clp53n.bkt.clouddn.com/_138.jpg",
    "http://op2clp53n.bkt.clouddn.com/0_ocs_fin_cov_1.jpg",
    "http://op2clp53n.bkt.clouddn.com/2voyage.jpg",
    "http://op2clp53n.bkt.clouddn.com/boa_illustrations_master_fb_1200x628-12.jpg",
    "http://op2clp53n.bkt.clouddn.com/building_science_bulletin_cover_2__1x.jpg",
    "http://op2clp53n.bkt.clouddn.com/building-science-bulletin-cover_1x.jpg",
    "http://op2clp53n.bkt.clouddn.com/chemistry4_1x.png",
    "http://op2clp53n.bkt.clouddn.com/first_colony_dribbble_copy.jpg"
];
let len = imgs.length;

/**
 * 遍歷imgs陣列,有序將所有圖片加載出來
 * 可以通過控制檯檢視網路請求,會發現所有圖片均按順序載入
 */
let count = 0;
load();

function load() {
    var imgObj = new Image();
    imgObj.src = imgs[count];

    $(imgObj).on('load error', function () { // 沒錯我使用了jQuery
        console.log(count);
        if (count >= len) {
            console.log('載入完畢');
            $('.container').addClass('active');
        } else {
            load(); // 繼續載入下一張
        }

        count++;
    });
}

將預載入封裝成jQuery外掛並使用

1.封裝成外掛

/**
 * 將圖片預載入封裝成外掛
 */
(function ($) {
    function Preload(imgs, options) {
        this.imgs = (typeof imgs === 'string') ? [imgs]: imgs; // 保證為陣列
        this.opts = $.extend({}, Preload.DEFAULTS, options); // 用options覆蓋預設值,然後生成一個新物件

        // 呼叫載入方法
        if (this.opts.order === 'ordered') {
            this._orderedLoad();
        } else {
            this._unorderedLoad(); // 無序載入
        }
    }

    // Preload預設值
    Preload.DEFAULTS = {
        order: 'unorder', // 預設無序載入
        each: null, // 接收一個方法,每一張圖片載入完成後呼叫該函式
        all: null // 接收一個方法,所有圖片載入完成後呼叫該函式
    };

    // 有序載入
    Preload.prototype._orderedLoad = function () {
        var imgs = this.imgs;
        var opts = this.opts;
        var count = 0;
        var len = imgs.length;

        function load() {
            var imgObj = new Image();
            imgObj.src = imgs[count];

            $(imgObj).on('load error', function () {
                if (count >= len) {
                    opts.all && opts.all(); // 全部載入完畢
                } else {
                    opts.each && opts.each(count); // 將當前正在載入的圖片索引傳遞出去
                    load();
                }

                count++;
            })
        }

        load();
    }

    // 無序載入
    Preload.prototype._unorderedLoad = function () {
        var imgs = this.imgs;
        var opts = this.opts;
        var count = 0; // 計數器
        var len = imgs.length;

        $.each(imgs, function (index, src) {
            if (typeof src != 'string') { // src路徑不是字串則不往下執行
                console.error('請傳入字串形式的圖片路徑');
                return;
            }

            var imgObj = new Image();
            imgObj.src = src;

            $(imgObj).on('load error', function () {
                opts.each && opts.each(count); // 首先判斷each屬性是否存在,存在則執行

                if (count >= len -1) {
                    opts.all && opts.all(); // 同理,不過是在圖片載入完成之後呼叫
                }

                count++;
            });
        });
    }

    // 掛載到jQuery物件上
    $.extend({
        preload: function (imgs, opts) { // 命名為preload
            new Preload(imgs, opts);
        }
    });
})(jQuery);

2.使用

<script src="js/jquery.min.js"></script>
<script src="js/preload.js"></script>
<script>
// 所有的圖片(要是網路太好,自己加圖片吧)
const imgs = [
    "http://op2clp53n.bkt.clouddn.com/20161104122758_cap-hpi.jpg",
    "http://op2clp53n.bkt.clouddn.com/500414621%20%281%29.jpg",
    "http://op2clp53n.bkt.clouddn.com/cover_bg.png",
    "http://img.aotu.io/mamboer/post-aotu.jpg",
    "http://misc.aotu.io/o2/img/books/books-cover.jpg",
    "http://img.aotu.io/Yettyzyt/cover.png",
    "http://img.aotu.io/wengeek/responsive-image.png",
    "https://gw.alicdn.com/tfs/TB1_6wnRXXXXXbwXFXXXXXXXXXX-900-500.jpg",
    "http://op2clp53n.bkt.clouddn.com/_138.jpg",
    "http://op2clp53n.bkt.clouddn.com/0_ocs_fin_cov_1.jpg",
    "http://op2clp53n.bkt.clouddn.com/2voyage.jpg",
    "http://op2clp53n.bkt.clouddn.com/boa_illustrations_master_fb_1200x628-12.jpg",
    "http://op2clp53n.bkt.clouddn.com/building_science_bulletin_cover_2__1x.jpg",
    "http://op2clp53n.bkt.clouddn.com/building-science-bulletin-cover_1x.jpg",
    "http://op2clp53n.bkt.clouddn.com/chemistry4_1x.png",
    "http://op2clp53n.bkt.clouddn.com/first_colony_dribbble_copy.jpg"
];

/**
 * 使用外掛,並有序載入
 */
$.preload(imgs, {
    order: 'ordered',
    each: function (count) {
        console.log('正在載入第' + (count + 1) + '張圖片');
    },
    all: function () {
        console.log('全部載入完成');
    }
});
</script>