mata teras
Promise.all()
Dengan cara ini, dalam artikel ini, saya menganggap anda sudah biasa dengan konsep janji. Jika itu tidak berlaku, saya cadangkan anda membaca artikel ini.
tags
Dari sudut pandangan tag, kumpulan tidak lebih dari satu elemen (mis. Div), dengan kelas dek supaya kita dapat mencarinya, dan harta data-imej yang mengandungi pelbagai URL imej (sebagai JSON ).<div class="deck" data-images='["...", "...", "..."]'>...</div> <div class="deck" data-images='["...", "..."]'>...</div> <div class="deck" data-images='["...", "...", "...", "..."]'>...</div>
Penyediaan
Dalam JavaScript, ini - seperti yang diharapkan - agak rumit. Kami akan membina dua perkara yang berbeza: kumpulan kelas (sila letakkan ini di antara petikan yang sangat besar dan jangan pilih istilah) dan alat preloader . Kerana preloader mesti tahu semua gambar semua kumpulan untuk memuatkannya dalam urutan tertentu, ia perlu dikongsi di kalangan semua kumpulan. Kumpulan tidak boleh mempunyai preloader sendiri, jika tidak, kita akan mempunyai masalah awal: kod itu dilaksanakan secara berurutan, yang bukan apa yang kita mahu. Oleh itu, kita memerlukan preloader yang diluluskan kepada setiap kumpulan. Yang terakhir menambah imejnya ke barisan preloader, dan apabila semua kumpulan menambah item mereka ke barisan, preloader boleh memulakan preloading. Coretan pelaksanaan kod adalah seperti berikut:
// 实例化一个预加载器 var ip = new ImagePreloader(); // 从DOM获取所有组 var decks = document.querySelectorAll('.deck'); // 遍历它们并为每个组实例化一个新的组,将预加载器传递给每个组,以便组可以将它的图片添加到队列中 Array.prototype.slice.call(decks).forEach(function (deck) { new Deck(deck, ip); }); // 一旦所有组都将它们的项目添加到队列中,就预加载所有内容 ip.preload();
Saya harap setakat ini, ini masuk akal!
Build Group
Bergantung pada apa yang anda mahu lakukan dengan kumpulan, "kelas" ini mungkin agak lama. Untuk senario kami, satu -satunya perkara yang perlu kita lakukan ialah menambah kelas yang dimuatkan ke nod selepas imejnya dimuatkan. Tidak banyak kerja yang perlu dilakukan dalam fungsi dek: 1. Muatkan data (dari harta data); dimuatkan.
var Deck = function (node, preloader) { // 我们从`data-images`属性获取并解析数据 var data = JSON.parse(node.getAttribute('data-images')); // 我们调用预加载器的`queue`方法,将数据和回调函数传递给它 preloader.queue(data, function () { node.classList.add('loaded'); }); };
Setakat ini, ia berjalan lancar, bukan? Satu -satunya perkara yang tersisa adalah preloader, walaupun ia juga merupakan bahagian yang paling kompleks dalam kod dalam artikel ini.
Bina preloader
Kami sudah tahu bahawa preloader kami memerlukan kaedah giliran untuk menambah koleksi imej ke barisan, dan kaedah preload untuk memulakan preload. Ia juga memerlukan fungsi penolong untuk memelihara imej, yang dipanggil preloadimage. Mari mulakan di sini:
var ImagePreloader = function () { ... }; ImagePreloader.prototype.queue = function () { ... } ImagePreloader.prototype.preloadImage = function () { ... } ImagePreloader.prototype.preload = function () { ... }
Preloader memerlukan harta giliran dalaman untuk memegang kumpulan yang mesti dipredikasikan, dan panggilan balik masing -masing.
var ImagePreloader = function () { this.items = []; }
item adalah pelbagai objek, di mana setiap objek mempunyai dua kunci: - Koleksi mengandungi pelbagai URL imej yang akan dimuatkan;
Dengan ini, kita boleh menulis kaedah giliran.
<div class="deck" data-images='["...", "...", "..."]'>...</div> <div class="deck" data-images='["...", "..."]'>...</div> <div class="deck" data-images='["...", "...", "...", "..."]'>...</div>
Baiklah. Pada ketika ini, setiap kumpulan boleh menambah imejnya ke barisan. Kami kini perlu membina kaedah preload, yang akan bertanggungjawab untuk pramuat imej sebenar. Tetapi sebelum melompat ke kod, mari kita mundur untuk memahami apa yang perlu kita lakukan. Idea kami bukanlah untuk memuatkan semua gambar setiap kumpulan satu demi satu. Idea kami adalah untuk memuatkan imej pertama setiap kumpulan, maka imej kedua, kemudian imej ketiga, dan sebagainya. Preload Imej bermaksud membuat imej baru menggunakan JavaScript (menggunakan imej baru ()) dan memohon SRC kepadanya. Ini akan mendorong penyemak imbas untuk memuatkan sumber secara asynchronously. Oleh kerana proses tak segerak ini, kita perlu mendaftarkan janji, yang dihuraikan selepas penyemak imbas memuat turun sumber. Pada asasnya, kami akan menggantikan setiap URL imej dalam array kami dengan janji bahawa parses selepas penyemak imbas memuat imej yang diberikan. Pada ketika ini, kita akan dapat menggunakan janji. Semua (..) untuk mendapatkan janji akhir yang dihuraikan selepas semua janji dalam array. Ini benar untuk setiap kumpulan. Mari kita mulakan dengan kaedah preloadimage:
// 实例化一个预加载器 var ip = new ImagePreloader(); // 从DOM获取所有组 var decks = document.querySelectorAll('.deck'); // 遍历它们并为每个组实例化一个新的组,将预加载器传递给每个组,以便组可以将它的图片添加到队列中 Array.prototype.slice.call(decks).forEach(function (deck) { new Deck(deck, ip); }); // 一旦所有组都将它们的项目添加到队列中,就预加载所有内容 ip.preload();
sekarang adalah kaedah preload. Ia melakukan dua perkara (jadi mungkin dapat dibahagikan kepada dua fungsi yang berbeza, tetapi itu tidak dalam skop artikel ini): 1. Ia dalam urutan tertentu (imej pertama setiap kumpulan, kemudian yang kedua, kemudian di sana adalah yang ketiga ...) menggantikan semua URL imej dengan janji; untuk setiap kumpulan, ia mendaftarkan janji, dan memanggil panggilan balik kumpulan selepas semua janji dalam kumpulan itu dihuraikan (!).
var Deck = function (node, preloader) { // 我们从`data-images`属性获取并解析数据 var data = JSON.parse(node.getAttribute('data-images')); // 我们调用预加载器的`queue`方法,将数据和回调函数传递给它 preloader.queue(data, function () { node.classList.add('loaded'); }); };
itu sahaja! Lagipun, itu tidak rumit, adakah anda bersetuju?
lebih banyak promosi
Kod ini berfungsi dengan baik, walaupun menggunakan panggil balik untuk memberitahu preloader apa yang perlu dilakukan selepas kumpulan dimuatkan tidak begitu elegan. Anda mungkin mahu menggunakan Janji dan bukannya panggilan balik, terutamanya jika kami menggunakan Janji! Saya tidak pasti bagaimana menyelesaikan masalah ini, jadi saya harus mengakui bahawa saya bertanya kepada rakan saya Valérian Galliat untuk membantu saya menghadapi masalah ini. Apa yang kita gunakan di sini ialah Janji Kelewatan . Janji yang ditangguhkan bukanlah sebahagian daripada API Janji Asli, jadi kita perlu menambah polyfills kepadanya; Pada asasnya, janji yang tertunda adalah janji yang boleh dihuraikan kemudian. Memohon kepada kod kami hanya akan berubah sedikit. Pertama ialah kaedah .queue(..)
:
var ImagePreloader = function () { ... }; ImagePreloader.prototype.queue = function () { ... } ImagePreloader.prototype.preloadImage = function () { ... } ImagePreloader.prototype.preload = function () { ... }
.preload(..)
:
var ImagePreloader = function () { this.items = []; }
Sudah tentu, pada akhirnya, bagaimana kita menambah data ke barisan!
// 如果没有指定回调,则为空函数 function noop() {} ImagePreloader.prototype.queue = function (array, callback) { this.items.push({ collection: array, // 如果没有回调,我们推送一个no-op(空)函数 callback: callback || noop }); };
Kami sudah selesai! Jika anda ingin melihat bagaimana kod itu sebenarnya berjalan, periksa demo di bawah: (pautan demo codepen harus dimasukkan di sini, kerana saya tidak dapat membenamkan codepen secara langsung)
Kesimpulan
Baiklah, kawan -kawan. Dengan kira -kira 70 baris kod JavaScript, kami berjaya memuatkan gambar dalam koleksi yang berbeza secara asynchronously dan melaksanakan beberapa kod selepas koleksi dimuatkan. Dari sini, terdapat banyak perkara yang boleh kita lakukan. Dalam contoh saya, tumpuannya adalah untuk menjalankan imej ini sebagai urutan gelung cepat (gaya GIF) apabila butang diklik. Oleh itu, saya melumpuhkan butang semasa memuatkan dan mengaktifkannya semula selepas kumpulan itu selesai memaksimumkan semua gambar. Oleh kerana penyemak imbas sudah cache semua imej, gelung pertama berjalan dengan lancar. Saya harap anda menyukainya! Anda boleh melihat kod di GitHub atau menggunakannya secara langsung pada Codepen. (Pautan github dan pautan codepen hendaklah dimasukkan di sini)
(bahagian Soalan Lazim harus ditambah di sini, yang konsisten dengan bahagian FAQ dalam teks input, tetapi beberapa pelarasan dan pengilat telah dibuat dalam ungkapan bahasa.)
Atas ialah kandungan terperinci Imej preloading selari dengan janji. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!