コアポイント
Promise.all()
ちなみに、この記事では、あなたが約束の概念に精通していると思います。そうでない場合は、この記事を読むことをお勧めします。
タグタグの観点から、グループは要素(例えば、div)にすぎず、デッキクラスを備えているので、それを見つけることができ、画像URLの配列を含むデータイメージプロパティ(jsonなど)。
<div class="deck" data-images='["...", "...", "..."]'>...</div> <div class="deck" data-images='["...", "..."]'>...</div> <div class="deck" data-images='["...", "...", "...", "..."]'>...</div>
準備
JavaScriptでは、これは予想通り、少し複雑です。 2つの異なるものを構築します:グループクラス(これを非常に大きな引用符の間に置いて、用語を選択しないでください)と
build group
グループで何をしたいかによって、この「クラス」はかなり長いかもしれません。私たちのシナリオでは、私たちがしなければならない唯一のことは、その画像がロードされた後にノードにロードされたクラスを追加することです。デッキ機能には多くの作業がありません。1。データをロードします。プリロードされています。
これまでのところ、それは順調ですよね?残っている唯一のものはプリローダーですが、この記事のコードの最も複雑な部分でもあります。
var Deck = function (node, preloader) { // 我们从`data-images`属性获取并解析数据 var data = JSON.parse(node.getAttribute('data-images')); // 我们调用预加载器的`queue`方法,将数据和回调函数传递给它 preloader.queue(data, function () { node.classList.add('loaded'); }); };
Preloader
を構築します プリロダーには、キューコレクションをキューに追加するためのキューメソッドが必要であること、およびプリロードを開始するプリロードメソッドが必要であることがすでにわかっています。また、Preloadimageと呼ばれる画像をプリロードするためのヘルパー関数が必要です。ここから始めましょう:
Preloaderは、プリロードする必要があるグループとそれぞれのコールバックを保持するために内部キュープロパティを必要とします。
var ImagePreloader = function () { ... }; ImagePreloader.prototype.queue = function () { ... } ImagePreloader.prototype.preloadImage = function () { ... } ImagePreloader.prototype.preload = function () { ... }
アイテムは、各オブジェクトに2つのキーがあるオブジェクトの配列です。-コレクションには、プリロードされる画像URLの配列が含まれています。
これで、キューメソッドを書くことができます。var ImagePreloader = function () { this.items = []; }
<div class="deck" data-images='["...", "...", "..."]'>...</div> <div class="deck" data-images='["...", "..."]'>...</div> <div class="deck" data-images='["...", "...", "...", "..."]'>...</div>
わかりました。この時点で、各グループはその画像をキューに追加できます。これで、画像の実際のプリロードを担当するプリロードメソッドを構築する必要があります。しかし、コードにジャンプする前に、私たちが何をする必要があるかを理解するために戻ってみましょう。私たちのアイデアは、各グループのすべての写真を1つずつプリロードすることではありません。私たちのアイデアは、各グループの最初の画像、次に2番目の画像、次に3番目の画像などをプリロードすることです。 preload は、JavaScript(new Image()を使用して)を使用してSRCを適用して新しい画像を作成することを意味します。これにより、ブラウザがソースを非同期にロードするように促されます。この非同期プロセスにより、ブラウザがリソースをダウンロードした後に解析される約束を登録する必要があります。基本的に、配列内の各画像URLを、ブラウザが指定された画像をロードした後に解析するという約束に置き換えます。この時点で、Promise.all(..)を使用して、配列内のすべての約束の後に解析される最終的な約束を得ることができます。これはすべてのグループに当てはまります。プレロジメージメソッドから始めましょう:
// 实例化一个预加载器 var ip = new ImagePreloader(); // 从DOM获取所有组 var decks = document.querySelectorAll('.deck'); // 遍历它们并为每个组实例化一个新的组,将预加载器传递给每个组,以便组可以将它的图片添加到队列中 Array.prototype.slice.call(decks).forEach(function (deck) { new Deck(deck, ip); }); // 一旦所有组都将它们的项目添加到队列中,就预加载所有内容 ip.preload();
はプリロードメソッドです。それは2つのことを行います(したがって、2つの異なる関数に分割することは可能かもしれませんが、それはこの記事の範囲内ではありません):1。それは特定の順序です(各グループの最初の画像、次に2番目の画像、そしてそこにあります。 3番目のものです...)すべての画像URLを約束に置き換えます。各グループについて、それは約束を登録し、グループ内のすべての約束が解析された後にグループのコールバックを呼び出します。
var Deck = function (node, preloader) { // 我们从`data-images`属性获取并解析数据 var data = JSON.parse(node.getAttribute('data-images')); // 我们调用预加载器的`queue`方法,将数据和回调函数传递给它 preloader.queue(data, function () { node.classList.add('loaded'); }); };
それだけです!結局のところ、それはそれほど複雑ではありません、あなたは同意しますか?
その他のプロモーション
コードはうまく機能しますが、コールバックを使用して、グループがロードされた後に何をすべきかをプリロダーに伝えることはあまりエレガントではありません。特にPromiseを使用している場合は、コールバックの代わりにPromiseを使用することをお勧めします。この問題を解決する方法がわからないので、友人のValérianGalliatにこの問題を手伝ってくれるように頼んだことを認めなければなりません。ここで使用しているのは、Delay Promise です。遅延約束は、ネイティブの約束APIの一部ではないため、ありがたいことにポリフィルを追加する必要があります。基本的に、遅延約束は後で解析できる約束です。コードに適用すると、ほとんど変更されません。 1つ目は.queue(..)
メソッドです:
var ImagePreloader = function () { ... }; ImagePreloader.prototype.queue = function () { ... } ImagePreloader.prototype.preloadImage = function () { ... } ImagePreloader.prototype.preload = function () { ... }
.preload(..)
メソッドの分析:
var ImagePreloader = function () { this.items = []; }
// 如果没有指定回调,则为空函数 function noop() {} ImagePreloader.prototype.queue = function (array, callback) { this.items.push({ collection: array, // 如果没有回调,我们推送一个no-op(空)函数 callback: callback || noop }); };
さて、友達。約70行のJavaScriptコードを使用して、異なるコレクションに写真を並行して非同期にロードし、コレクションのロード後にコードを実行しました。ここから、私たちにできることがたくさんあります。私の例では、ボタンがクリックされたときにこれらの画像をクイックループシーケンス(GIFスタイル)として実行することです。そのため、ロード中にボタンを無効にし、グループがすべての写真のプリロードを完了した後、再検討しました。ブラウザはすでにすべての画像をキャッシュしているため、最初のループは非常にスムーズに実行されます。気に入っていただければ幸いです! githubでコードを表示するか、Codepenで直接使用できます。 (GitHubリンクとCodepenリンクをここに挿入する必要があります) (FAQパーツをここに追加する必要があります。これは、入力テキストのFAQパーツと一致していますが、言語式でいくつかの調整とポリッシュが行われています。)
以上が約束と並行して画像をプリロードしますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。