近年の HTML の最も優れた改良点の 1 つは、画像 (iframe も含む) に追加できる、ブラウザーにビューポートに表示されるまでの画像。
<img src="/images/your-image.png" loading="lazy">
とてもシンプルでとても便利です。しかし、これをスクリプトでも実行できたら素晴らしいと思いませんか。これにより、コンポーネントが実際に必要な場合にのみ、コンポーネントを遅延ロードできるようになります...
さて、もう 1 つの機能として、要素には、onload 属性と onerror 属性を使用して画像が読み込まれた (または読み込まれていない) 後 にスクリプトを実行する機能があります。
<img src="/images/your-image.png" loading="lazy" onload="() => console.log('image loaded')" >
この onload の「コールバック」は、画像がロードされたときにのみ起動され、画像が遅延ロードされている場合は、画像がビューポートにあるときにのみ起動されます。さあ!遅延ロードされたスクリプト。
残念ながら、このままではあまり役に立ちません。まず、ページ上に不要な画像が表示されます。次に、実行したい JavaScript をインライン化する必要があります。これでは遅延読み込みの目的が損なわれます。したがって、これを改善するためにいくつかの変更を加えてみましょう。
画像自体は何でも構いませんが、もっと重要なことに、何もなくても構いません。前に述べたように、onerror コールバックがあります。これは、名前が示すように、画像が読み込まれないときに起動されます。
これは、存在しないイメージを src に指定する必要があるという意味ではありません。その場合、コンソールにイメージの欠落に関する赤い 404 エラーが表示されますが、誰もそれを望んでいません。
onerror コールバックは、src 画像が実際には画像でない場合にも起動されます。そのための最も簡単な方法は、data: 形式を使用して画像を「不正にエンコード」することです。これには、画像が見つからないという警告でコンソールがいっぱいにならないという利点もあります?
<img src="data:," loading="lazy" onerror="() => console.log('image not loaded')" >
この場合もページには「壊れた画像」サムネイルが表示されますが、それについては後ほど説明します。
わかりました。しかし、実行したい JavaScript をインライン化する必要があるので、それをどう修正すればよいでしょうか?
ES モジュールのサポートがほぼ普遍的になったので、非常に強力な event-import-then-default JavaScript 読み込みテクニックを使用して、次のようにイベントの発生後にスクリプトを読み込むことができます。
<img src="data:," loading="lazy" onerror="import('/js/some-component.js').then(_ => _.default(this))" >
注: これは、onclick、onchange などのイベントにも機能します
注: アンダースコアはモジュールにアクセスするための簡略的な方法です。.then(Module => Module.default(this))
それで、ここで何が起こっているのですか?
まず、いくつかのコンポーネントがどのようなものかを見てみましょう:
// some-component.js export default element => { element.outerHTML = ` <div class="whatever"> <p>Hello world!</p> </div> `; }
お気づきかもしれませんが、onerror コールバックで、これを引数としてデフォルトのエクスポートに渡しました。私が これ を実行した理由は (ダジャレですみません ?)、スクリプトに を与えるためでした。 this (またやった?) context this = .
にあるので、それが呼び出されています。これで、単純に element.outerHTML を実行して壊れた画像を HTML マークアップに置き換えることができ、遅延読み込みされたスクリプトが完成しました。 ?
この手法をページ上で複数回使用する場合は、「キャッシュ無効化」インデックス、または乱数をデータに渡す必要があります。たとえば、次のようなものです。
<img src="data:,abc123" loading="lazy" onerror="import('/js/some-component.js').then(_ => _.default(this))" > <img src="data:,xyz789" loading="lazy" onerror="import('/js/some-other-component.js').then(_ => _.default(this))" > </p> <p>「:,」の後の文字列は、異なるものであれば何でも構いません。</p> <p>関数にパラメータを渡す非常に簡単な方法は、次のように HTML で data-something 属性を使用することです。</p> <pre class="brush:php;toolbar:false"> <img src="data:," loading="lazy" data-message="hello world" onerror="import('/js/some-component.js').then(_ => _.default(this))" >
this を関数に渡しているため、次のようにデータ属性にアクセスできます。
export default element => { const { message } = element.dataset element.outerHTML = ` <div class="whatever"> <p>${message}</p> </div> `; }
ぜひコメント欄でご意見をお聞かせください。 ❤️
以上が画像などの Lazyload スクリプトの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。