Kata pengantar
ImagePool adalah alat JS untuk mengelola pemuatan gambar. ImagePool dapat mengontrol jumlah pemuatan gambar bersamaan.
Untuk pemuatan gambar, cara yang paling primitif adalah dengan menulis tag IMG secara langsung, seperti: <img src = "Url gambar" />.
Setelah optimasi terus menerus, skema pemuatan penundaan gambar telah muncul. Kali ini, URL gambar tidak ditulis secara langsung dalam atribut SRC, tetapi dalam atribut tertentu, seperti: <img src = "" data-src = "URL gambar" />. Dengan cara ini, browser tidak akan secara otomatis memuat gambar. Ketika waktu yang tepat diperlukan, gunakan JS untuk menempatkan URL di atribut data-SRC ke atribut SRC dari tag IMG, atau setelah membaca URL, gunakan JS untuk memuat gambar, dan atur atribut SRC setelah memuat, dan tampilkan gambar.
Ini tampaknya terkontrol dengan baik, tetapi masih akan ada masalah.
Meskipun hanya dapat memuat bagian dari gambar, bagian gambar ini mungkin masih merupakan urutan besarnya yang relatif besar.
Ini bukan masalah besar bagi sisi PC, tetapi untuk sisi seluler, terlalu banyak gambar bersamaan dimuat, yang sangat mungkin menyebabkan crash aplikasi.
Oleh karena itu, kami sangat membutuhkan mekanisme buffering gambar untuk mengontrol konkurensi pemuatan gambar. Mirip dengan kumpulan koneksi database backend, tidak membuat terlalu banyak koneksi, dan dapat sepenuhnya menggunakan kembali setiap koneksi.
Pada titik ini, ImagePool lahir.
Diagram skematik yang buruk
Petunjuk Penggunaan
Pertama, inisialisasi kumpulan koneksi:
var imagepool = incitimagePool (5);
InitiMagePool adalah metode global yang dapat digunakan langsung di mana saja. Fungsinya adalah untuk membuat kumpulan koneksi, dan Anda dapat menentukan jumlah maksimum koneksi ke kumpulan koneksi, secara opsional, standarnya adalah 5.
Di halaman yang sama, beberapa panggilan ke incitAmagepool mengembalikan instance inti yang sama, yang selalu merupakan yang pertama, dengan sedikit perasaan singleton. Misalnya:
Salinan kode adalah sebagai berikut:
var imagepool1 = incitimagePool (3);
var imagepool2 = incitimagePool (7);
Pada saat ini, jumlah maksimum koneksi antara ImagePool1 dan ImagePool2 adalah 3, dan instance inti yang sama digunakan secara internal. Perhatikan bahwa inti internal adalah sama, bukan imagepool1 === ImagePool2.
Setelah inisialisasi, Anda dapat memuat gambar dengan percaya diri.
Cara termudah untuk menelepon adalah sebagai berikut:
Salinan kode adalah sebagai berikut:
var imagepool = incitimagePool (10);
ImagePool.Load ("Url Image", {
Sukses: function (src) {
console.log ("Success :::::"+SRC);
},
Kesalahan: function (src) {
console.log ("error ::::"+src);
}
});
Panggil saja metode pemuatan pada instance.
Metode beban memiliki dua parameter. Parameter pertama adalah URL gambar yang perlu dimuat, dan parameter kedua adalah berbagai opsi, termasuk callback yang berhasil dan gagal. URL gambar akan diteruskan selama panggilan balik.
Dengan cara ini, Anda hanya bisa lulus dalam satu gambar, sehingga juga dapat ditulis dalam bentuk berikut:
Salinan kode adalah sebagai berikut:
var imagepool = incitimagePool (10);
ImagePool.Load (["Image 1Url", "Image 2Url"], {
Sukses: function (src) {
console.log ("Success :::::"+SRC);
},
Kesalahan: function (src) {
console.log ("error ::::"+src);
}
});
Dengan meneruskan array URL gambar, Anda dapat melewati beberapa gambar.
Ketika setiap gambar berhasil dimuat (atau gagal), metode keberhasilan (atau kesalahan) akan dipanggil dan URL gambar yang sesuai akan dilewati.
Tetapi kadang -kadang kita tidak perlu sering menelepon balik seperti ini. Lewati dalam array URL gambar. Ketika semua gambar dalam array ini diproses, maka panggilan balik sudah cukup.
Tambahkan saja satu opsi:
Salinan kode adalah sebagai berikut:
var imagepool = incitimagePool (10);
ImagePool.Load (["Image 1Url", "Image 2Url"], {
Sukses: function (Sarray, earray, count) {
Console.log ("Sarray ::::"+Sarray);
Console.log ("Earray ::::"+Earray);
Console.log ("Count :::::"+Count);
},
Kesalahan: function (src) {
console.log ("error ::::"+src);
},
Sekali: Benar
});
Dengan menambahkan atribut sekali ke opsi dan mengaturnya ke True, Anda hanya dapat mencapai panggilan balik sekali.
Kali ini, metode keberhasilan harus dipanggil kembali, dan metode kesalahan diabaikan saat ini.
Pada saat ini, metode Callback Success tidak lagi lewat dalam parameter URL gambar, tetapi lulus dalam tiga parameter, yaitu: array URL yang berhasil, array URL yang gagal, dan jumlah total gambar yang diproses.
Selain itu, ada cara untuk mendapatkan keadaan internal dari kumpulan koneksi:
Salinan kode adalah sebagai berikut:
var imagepool = incitimagePool (10);
console.log (imagepool.info ());
Dengan memanggil metode info, Anda bisa mendapatkan keadaan internal dari kumpulan koneksi pada waktu saat ini, dan struktur data adalah sebagai berikut:
Object.task.Count Jumlah tugas yang menunggu untuk diproses di kumpulan koneksi
Object.thread.count Jumlah maksimum koneksi ke kumpulan koneksi
Object.thread. Jumlah bebas koneksi gratis ke kumpulan koneksi
Disarankan untuk tidak sering memanggil metode ini.
Akhirnya, perlu dicatat bahwa jika gambar gagal memuat, itu akan mencoba paling banyak 3 kali. Jika gambar gagal memuat di akhir, metode kesalahan akan dipanggil kembali. Jumlah upaya dapat dimodifikasi dalam kode sumber.
Akhirnya, izinkan saya menekankan bahwa pembaca dapat mendorong gambar ke kumpulan koneksi sebanyak mungkin, tanpa khawatir tentang konkurensi yang berlebihan. ImagePool akan membantu Anda memuat gambar -gambar ini dengan berantakan.
Akhirnya, harus dicatat bahwa ImagePool tidak akan secara teoritis mengurangi kecepatan pemuatan gambar, itu hanya pemuatan yang mulus.
Kode Sumber
Salinan kode adalah sebagai berikut:
(fungsi (ekspor) {
//Lajang
var instance = null;
var kosongfn = function () {};
// konfigurasi default awal
var config_default = {
// Jumlah "utas" di kumpulan utas
Thread: 5,
// Jumlah coba lagi gagal memuat gambar
// Coba dua kali, tambahkan yang asli, total 3 kali
"Coba": 2
};
//alat
var _helpers = {
// Atur atribut DOM
setAttr: (function () {
var img = gambar baru ();
// menilai apakah browser mendukung dataset HTML5
if (img.dataset) {
return function (dom, name, value) {
dom.dataset [name] = value;
nilai pengembalian;
};
}kalau tidak{
return function (dom, name, value) {
dom.setAttribute ("data-"+nama, nilai);
nilai pengembalian;
};
}
} ()),
// Dapatkan atribut DOM
getAttr: (function () {
var img = gambar baru ();
// menilai apakah browser mendukung dataset HTML5
if (img.dataset) {
return function (dom, name) {
return dom.dataset [name];
};
}kalau tidak{
return function (dom, name) {
return dom.getAttribute ("data-"+name);
};
}
} ())
};
/**
* Metode pembuatan
* @param max jumlah maksimum koneksi. Nilai.
*/
function imagePool (max) {
// Jumlah Maksimum Konkurensi
this.max = maks || config_default.thread;
this.linkhead = null;
this.linkNode = null;
// memuat kolam
// [{img: dom, gratis: true, node: node}]
// node
// {src: "", options: {Success: "fn", error: "fn", sekali: true}, coba: 0}
this.pool = [];
}
/**
* Inisialisasi
*/
ImagePool.prototype.initpool = function () {
var i, img, obj, _s;
_s = ini;
untuk (i = 0; i <this.max; i ++) {
obj = {};
img = gambar baru ();
_helpers.setAttr (img, "id", i);
img.onload = function () {
var id, src;
// panggilan balik
//_s.getnode(this).options.success.call(null, this.src);
_s.notice (_s.getnode (ini), "Sukses", this.src);
// Tugas Memproses
_s.executeLink (ini);
};
img.onError = function (e) {
var node = _s.getnode (ini);
// menilai jumlah upaya
if (node.try <config_default.try) {
node.try = node.try + 1;
// Tambahkan ke akhir daftar tugas lagi
_s.applnode (_s.createNode (node.src, node.options, node.notice, node.group, node.try));
}kalau tidak{
// callback kesalahan
//node.options.error.call(null, this.src);
_s.notice (node, "error", this.src);
}
// Tugas Memproses
_s.executeLink (ini);
};
obj.img = img;
obj.free = true;
this.pool.push (obj);
}
};
/**
* Enkapsulasi panggilan balik
* Node Node @param. Obyek.
* Status status @param. Rangkaian. Nilai Opsional: Sukses | Kesalahan (Gagal)
* Jalur gambar @param src. Rangkaian.
*/
ImagePool.prototype.notice = function (node, status, src) {
node.notice (status, src);
};
/**
* Memproses tugas daftar tertaut
* Objek dom gambar dom @param. Obyek.
*/
ImagePool.prototype.executeLink = function (dom) {
// Jelaskan apakah ada node dalam daftar tertaut
if (this.linkhead) {
// Muat gambar berikutnya
this.setsrc (dom, this.linkhead);
// Lepaskan header tautan
this.shiftnode ();
}kalau tidak{
// Atur status Anda sendiri ke IDLE
this.status (dom, true);
}
};
/**
* Dapatkan "utas" idle
*/
ImagePool.Prototype.getFree = function () {
panjang var, i;
untuk (i = 0, panjang = this.pool.length; i <panjang; i ++) {
if (this.pool [i] .free) {
kembalikan ini.pool [i];
}
}
kembali nol;
};
/**
* Mengenak pengaturan atribut SRC
* Karena mengubah atribut SRC setara dengan memuat gambar, merangkum operasi
* Objek dom gambar dom @param. Obyek.
* Node Node @param. Obyek.
*/
ImagePool.prototype.setsrc = function (dom, node) {
// Atur "utas" di kolam untuk menjadi non-idle
this.status (dom, false);
// simpul yang berafiliasi
this.setnode (dom, node);
// Muat gambar
dom.src = node.src;
};
/**
* Perbarui status "utas" di kumpulan
* Objek dom gambar dom @param. Obyek.
* Status status @param. Boolean. Nilai Opsional: Benar (Idle) | false (non-idle)
*/
ImagePool.prototype.status = function (dom, status) {
var id = _helpers.getAttr (dom, "id");
this.pool [id] .free = status;
// status idle, hapus node yang terkait
if (status) {
this.pool [id] .node = null;
}
};
/**
* Perbarui simpul yang terkait dari "utas" di kumpulan
* Objek dom gambar dom @param. Obyek.
* Node Node @param. Obyek.
*/
ImagePool.prototype.setNode = function (dom, node) {
var id = _helpers.getAttr (dom, "id");
this.pool [id] .node = node;
kembalikan node ini.pool [id] .node ===;
};
/**
* Dapatkan simpul terkait "utas" di kolam renang
* Objek dom gambar dom @param. Obyek.
*/
ImagePool.prototype.getNode = function (dom) {
var id = _helpers.getAttr (dom, "id");
kembalikan ini.pool [id] .node;
};
/**
* Antarmuka eksternal, muat gambar
* @param src dapat berupa string SRC atau array string SRC.
* @param opsi parameter yang ditentukan pengguna. Termasuk: Panggilan balik sukses, panggilan balik kesalahan, sekali tag.
*/
ImagePool.Prototype.Load = function (src, opsi) {
var srcs = [],
Gratis = NULL,
panjang = 0,
i = 0,
// Hanya menginisialisasi strategi panggilan balik sekali
natangan = (function () {
if (options.once) {
fungsi pengembalian (status, src) {
var g = this.group,
o = this.Options;
//Catatan
g [status] .push (src);
// Jelaskan apakah semua reorganisasi telah diproses
if (g.success.length + g.error.length === g.count) {
// asinkron
// Faktanya, itu dieksekusi secara terpisah sebagai tugas lain untuk mencegah fungsi panggilan balik terlalu lama dan mempengaruhi kecepatan pemuatan gambar
setTimeout (function () {
o.success.call (null, g.success, g.error, g.count);
}, 1);
}
};
}kalau tidak{
fungsi pengembalian (status, src) {
var o = this.options;
// Langsung panggilan balik
setTimeout (function () {
o [status] .call (null, src);
}, 1);
};
}
} ()),
grup = {
Hitung: 0,
kesuksesan: [],
Kesalahan: []
},
node = null;
opsi = opsi || {};
options.success = options.success || kosong;
options.Error = options.Error || kosong;
srcs = srcs.concat (src);
// Tetapkan jumlah elemen grup
group.count = srcs.length;
// bepergian melalui gambar yang perlu dimuat
untuk (i = 0, panjang = srcs.length; i <panjang; i ++) {
// Buat node
node = this.createNode (srcs [i], opsi, pemberitahuan, grup);
// menilai apakah kumpulan utas gratis
free = this.getFree ();
if (gratis) {
// Jika Anda memiliki waktu luang, segera muat gambarnya
this.setsrc (free.img, node);
}kalau tidak{
// No Idle, tambahkan tugas ke daftar yang ditautkan
this.appendNode (node);
}
}
};
/**
* Dapatkan informasi status internal
* @returns {{}}
*/
ImagePool.prototype.info = function () {
var info = {},
panjang = 0,
i = 0,
node = null;
//Benang
info.thread = {};
// Jumlah total utas
info.thread.count = this.pool.length;
// Jumlah utas idle
info.thread.free = 0;
//Tugas
info.task = {};
// Jumlah tugas yang tertunda
info.task.count = 0;
// Dapatkan jumlah "utas" gratis
untuk (i = 0, panjang = this.pool.length; i <panjang; i ++) {
if (this.pool [i] .free) {
info.thread.free = info.thread.free + 1;
}
}
// Dapatkan jumlah tugas (panjang rantai tugas)
node = this.linkhead;
if (node) {
info.task.count = info.task.count + 1;
while (node.next) {
info.task.count = info.task.count + 1;
node = node.next;
}
}
pengembalian info;
};
/**
* Buat node
* Jalur gambar @param src. Rangkaian.
* @param opsi parameter yang ditentukan pengguna. Termasuk: Panggilan balik sukses, panggilan balik kesalahan, sekali tag.
* @param pemberitahuan strategi panggilan balik. fungsi.
* Informasi grup grup @param. Obyek. {Count: 0, Success: [], error: []}
* @param TR Jumlah kesalahan coba lagi. Nilai. Standarnya adalah 0.
* @returns {{}}
*/
ImagePool.prototype.createNode = fungsi (src, opsi, pemberitahuan, grup, tr) {
var node = {};
node.src = src;
node.options = opsi;
node.notice = natas;
node.group = grup;
node.try = tr || 0;
return node;
};
/**
* Tambahkan node ke akhir daftar tugas
* Node Node @param. Obyek.
*/
ImagePool.Prototype.appendNode = function (node) {
// menilai apakah daftar yang ditautkan kosong
if (! this.linkhead) {
this.linkhead = node;
this.linknode = node;
}kalau tidak{
this.linknode.next = node;
this.linknode = node;
}
};
/**
* Hapus header tautan
*/
ImagePool.Prototype.ShiftNode = function () {
// Jelaskan apakah ada node dalam daftar tertaut
if (this.linkhead) {
// Ubah header daftar tautan
this.linkhead = this.linkhead.next || batal;
}
};
/**
* Ekspor Antarmuka Eksternal
* @param max jumlah maksimum koneksi. Nilai.
* @returns {{load: function, info: function}}
*/
Exports.InitimagePool = function (max) {
if (! instance) {
instance = new imagePool (max);
instance.initpool ();
}
kembali {
/**
* Memuat gambar
*/
load: function () {
instance.load.Apply (instance, argumen);
},
/**
* Informasi internal
* @returns {* | any | void}
*/
info: function () {
return instance.info.call (instance);
}
};
};
}(ini));
Di atas adalah contoh cara menggunakan manajer pemuatan gambar front-end javascript yang luar biasa ini. Sudahkah Anda belajar cara menggunakannya?