【CSS + JS】テキストの無限ループアニメーション
「imagesLoaded」を使って
画像の読み込みを検知する
目次
imagesLoadedって?
画像を読み込んだあとに何か実行したい場合に使えるJavaScriptライブラリです。
どこで使うのか
主に画像の初回読み込みで起きる不具合への対応や、画像を読み込まんでいないと実行できないアニメーションなどに使えると思います。
僕が使う場面としては、最近でいうとこのブログでもよく紹介させていただいている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タイプあります。
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
についている背景画像の読み込みを検知してくれます。
イベント
always
・done
・fail
・progress
の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を作って動かしてみたいと思います。
画像を読み込むまでの間、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
NEW POSTS
【WordPress】GA4連携の人気記事ランキング機能を自作プラグイン化してみた
【netlify】ビルドイメージを更新 [ Ubuntu Xenial 16.04 → Ubuntu Focal 20.04 ]
【PHP】Google Business Profile APIを使ってクチコミを取得する
スクリーンショットのAPI「screendot」を使ってみた
【window.matchMedia】メディアクエリでhoverが使えるデバイスを判定
lax.jsの使い方【スクロール連動アニメーションの実装】