「imagesLoaded」を使って
画像の読み込みを検知する

imagesLoadedって?

画像を読み込んだあとに何か実行したい場合に使えるJavaScriptライブラリです。

imagesLoaded

どこで使うのか

主に画像の初回読み込みで起きる不具合への対応や、画像を読み込まんでいないと実行できないアニメーションなどに使えると思います。

僕が使う場面としては、最近でいうとこのブログでもよく紹介させていただいているBASEデザインマーケットのテンプレートの作成時です。
毎回IE11対応が必須という苦行があるのでそこで活躍します。
特に活躍するのが画像周りのチラつき対策です。
例えば最近はCSSのobject-fitをよく使うのですが、IE11は非対応なのでpolyfillを読み込ませます。 そのpolyfillを読み込んで適用するまでの一瞬、画像が歪んだり拡大されたりすることがあります。 これをimagesLoadedを使うことで対策できます。
その他にもAjaxで追加したコンテンツ画像や無限ループのスライドショーでクローンされる画像などなど、画像のチラつきが発生しそうな部分がかなりありますが、これらが全部一発で解決。

なんかJSでイベント書いてあれこれしてみたり、スライドショーライブラリのコールバック関数調べてあれやこれやしたりしてたんですが、imagesLoadedで簡単に解決! 容量も圧縮すると5~6kbほどなので軽いのでおすすめです。

ブラウザ対応状況

  • IE9+
  • Android 2.3+
  • iOS Safari 4+
  • All other modern browsers

公式ではこのようになっています。
imagesLoaded v3 を使うとIE8も対応できるみたいです。

imagesloadedのインストール

3パターンあります。

ダウンロードして使う

リンク先のソースをローカルのファイルにコピペして使います。
圧縮版、通常盤の2タイプあります。

圧縮版
imagesloaded.pkgd.min.js 

通常盤
imagesloaded.pkgd.js

CDNから読み込む

圧縮版、通常盤のどちらかを読み込みます。

<!-- 圧縮版 -->
<script src="https://unpkg.com/imagesloaded@4/imagesloaded.pkgd.min.js"></script>
<!-- 通常盤 -->
<script src="https://unpkg.com/imagesloaded@4/imagesloaded.pkgd.js"></script>

npm・Yarnでインストール

以下のコマンドのどちらかでローカルにインストールして使います。

$ npm install -D imagesloaded
$ yarn add -D imagesloaded

この場合はWebpackでimportして使いましょう。

import imagesLoaded from 'imagesloaded'

imagesLoadedの使い方

jQueryと併用する場合

$('#container').imagesLoaded( function() {
  // 画像を読み込んだ後に実行したい処理
});

// オプションを付ける場合
$('#container').imagesLoaded( {
  // imagesLoadedのオプション
  },
  function() {
    // 画像を読み込んだ後に実行したい処理
  }
);

ネイティブの場合

const elem    = document.querySelector('#container');
const calback = (instance) => {
  // 画像を読み込んだ後に実行したい処理
};
imagesLoaded( elem, callback )

// オプションを付ける場合
imagesLoaded( elem, options, callback )

// インスタンス化して使う場合
new imagesLoaded( elem, callback )

これで#container内にある画像の読み込みを検知してくれます。
基本的にはこれだけ。 めちゃくちゃ簡単です!

背景画像の読み込みに対応する

これが個人的にimagesLoadedのいちばん素敵な機能です。

// jQuery
$('#container').imagesLoaded( { background: true }, function() {
  // 画像を読み込んだ後に実行したい処理
});

// ネイティブ
imagesLoaded( '#container', { background: true }, function() {
  // 画像を読み込んだ後に実行したい処理
});

imageLoadedのオプションに{ background: true }を書いてあげると指定した要素の背景画像の読み込みも検知してくれます!これは便利!

また、{ background: '.item' }のようにしてあげると、#container内の子要素.itemについている背景画像の読み込みを検知してくれます。

イベント

alwaysdonefailprogressの4つのイベントを設定できます。

jQuery

$('#container').imagesLoaded()
.always( function( instance ) {
  //壊れている画像も含めて全ての画像を読み込んだら実行
})
.done( function( instance ) {
  //壊れている画像以外の全ての正常な画像を読み込んだら実行
})
.fail( function() {
  //壊れた画像を一つでも読み込んだら実行
})
.progress( function( instance, image ) {
  //画像をひとつずつ読み込み完了を検知
 const result = image.isLoaded ? '読み込まれました' : '壊れています';
  console.log(`${image.img.src}${result}`);
});

jQueryはメソッドチェーンが使えますね。
引数に関しては以下。

  • instance imagesLoadedインスタンス
  • image 読み込んだ画像

ネイティブ

imagesLoaded.on( 'always', function( instance ) {
  //壊れている画像も含めて全ての画像を読み込んだら実行
});

imagesLoaded.on( 'done', function( instance ) {
  //壊れている画像以外の全ての正常な画像を読み込んだら実行
});

imagesLoaded.on( 'fail', function( instance ) {
  //壊れた画像を一つでも読み込んだら実行
});

imagesLoaded.on( 'progress', function( instance, image ) {
  //画像をひとつずつ読み込み完了を検知
 const result = image.isLoaded ? '読み込まれました' : '壊れています';
  console.log(`${image.img.src}${result}`);
});

実際に使ってみる

ここまでは公式サイトをなぞっただけなので、実際にDEMOを作って動かしてみたいと思います。

すべての画像を読み込んだら実行するDEMO

画像を読み込むまでの間、CSSでプレースホルダー的に見せておいて、正常に読み込んだらLoaded、画像が壊れている場合はBrokenという文言を画像と一緒に表示させるということをしてみました。

const $cover = document.getElementById('js-cover');
//#js-coverに対してimagesLoadedを適用する
const imgLoad = imagesLoaded( $cover );
//すべての読み込みが完了した時
imgLoad.on('always', () => {
  //全て読み込んだらクラスを付ける
  console.log('always');
  $cover.classList.add('complete');
});
//正常に読み込んだ時
imgLoad.on('done', () => {
  console.log('done');
});
//壊れている画像がひとつでもある時
imgLoad.on('fail', () => {
  console.log('fail');
});
//一枚ずつ正常に読み込めたかどうかを判定
imgLoad.on('progress', (instance, image) => {
  //読み込めた場合に親要素にclassを付ける
  const parent    = image.img.parentNode;
  const className = image.isLoaded ? 'loaded' : 'broken';
  parent.classList.add(className);
});

ポイントはここ。

//#js-coverに対してimagesLoadedを適用する
const imgLoad = imagesLoaded( $cover );

公式にはjQueryで各イベントの使い方は載っていますが、ネイティブでの書き方のサンプルが微妙にわかりにくいです。 どうやって要素を指定するのかなと思ったんですが、jQueryの方のサンプルを見ると関数におそらく戻り値があるのでこれを変数にいれちゃえば使えるのかな?と思ったら使えました。

全体を通してやっていることは各タイミングでクラスの付け替えだけなので、CSSは割愛します。

実際デモを作ってみると、読み込みに時間のかかるような解像度の高い画像を多数読み込むサイトや、さらにそれを複数読み込んでアニメーションさせるような実装を考えている場合などはローディングとして簡単に使えるなと思いました。
背景画像にも使えますし。

さいごに

今回は画像の読み込みを検知するライブラリ「imagesLoaded」をご紹介しました。
Webサイトを作るときってけっこうな割合で画像周りの対策ばっかり考えなきゃいけないのでこういうライブラリがあるとローディングなども作りやすいし助かりますね。

記事一覧

RELATED

inoue
TIPS

【CSS + JS】テキストの無限ループアニメーション

inoue
TIPS

【Shopify】カートへの遷移を飛ばしてチェックアウトに進むボタンを設置する

inoue
TIPS

【JS】PhotoSwipe v5を使って画像をポップアップ表示する

inoue
TIPS

gulpでjpg・pngからAVIF画像を生成する

inoue
TIPS

【JS】MutationObserverでDOMを監視[PhotoSwipe(v5)+Swiper(v8)連携]

inoue
TIPS

【Google Sheets API】 スプレッドシートのデータをJSONで取得する

NEW POSTS

inoue
TRY

【WordPress】GA4連携の人気記事ランキング機能を自作プラグイン化してみた

inoue
TRY

【netlify】ビルドイメージを更新 [ Ubuntu Xenial 16.04 → Ubuntu Focal 20.04 ]

inoue
TIPS

【PHP】Google Business Profile APIを使ってクチコミを取得する

inoue
TRY

スクリーンショットのAPI「screendot」を使ってみた

inoue
TIPS

【window.matchMedia】メディアクエリでhoverが使えるデバイスを判定

inoue
TIPS

lax.jsの使い方【スクロール連動アニメーションの実装】

ブログ記事一覧
  • HOME
  • TIPS
  • 「imagesLoaded」を使って画像の読み込みを検知する