[jQuery] 画像ロード中の表示の実装
jQueryで画像(imgタグ)のURLを入れ替えた時に、画像読み込み中を表すロードインジケーターを表示する処理をしてみました。
説明
予めロードインジケータを画像表示の前に配置しておきます。
画像が読み込み完了した際にイベントが走るので、それを利用してロードインジケータの表示を制御(非表示化)します。
尚、画像がキャッシュされている際(切り替え後に既にロード済み)にイベントが走らない場合があるようで、その為、切り替え後に状態を確認し未ロードの場合のみインジケータを再表示します。
1、HTML上でロードインジケーターを画像の前に配置
画像がロードされるエリアおよびimgタグを予め用意しておき、その上に重なるようにロードインジケーター部分を配置しておきます。スクリプトで表示を制御する為、固有のIDを設定しておきます。
例「img_load_indicator.html」
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>画像読み込み中にロードインジケーターを表示</title> <script type="text/javascript" src="jquery-3.3.1.min.js"></script> <script type="text/javascript" src="img_load_indicator_controll.js"></script> <style> #image_view { position: relative; overflow: hidden; width:800px; height:600px; background: #333; } #image_view #description { z-index: 1; position: absolute; top: 0.5em; left: 0.5em; color: #888; } #image_view #load_image { z-index: 2; position: absolute; width:100%; height:auto; } #image_view #indicator { z-index: 3; width: 160px; height: 100px; text-align: center; color: #fff; position: absolute; top: 0; left: 0; right: 0; bottom: 0; margin: auto; display: none; /* あらかじめ非表示化しておく */ } #image_view #indicator img { display: block; margin: 0 auto; width: 80px; height: 80px; } .thumnail { display: inline-block; width:88px; height:88px; } </style> </head> <body> <h2>画像を表示</h2> <div id="image_view"> <div id="description"> ここに画像が表示されます。 </div> <!-- ロードインジケーター部分 --> <div id="indicator"> <img src="images/load_indicator.gif"><br> 画像をロード中 </div> <!-- ここまで --> <img src="" id="load_image"> </div> <h3>サムネイル</h3> <img src="images/photo01_thum.jpg" class="thumnail img_01"> <img src="images/photo02_thum.jpg" class="thumnail img_02"> <img src="images/photo03_thum.jpg" class="thumnail img_03"> <p>サムネイルをクリックするとロードします。</p> </body> </html>
ちょっとCSS部分が大きめですが重要なのは下の方です。
2、imgの切り替えに合わせロードインジケーターの表示を制御
URL切り替えに合わせ、キャッシュされてない場合にインジケーターを表示します。
そして、画像の読み込み完了時のイベントに、ロードインジケーターを消す処理を予め入れておきます。
尚、これとは別に、サムネイルをクリックしたら画像を入れ替える処理も行っています。
例「img_load_indicator_controll.js」
// サムネイルのクラス名と画像データ設定 var pictures = [ { thum_class : ".img_01", image_url : "images/photo01.jpg" }, { thum_class : ".img_02", image_url : "images/photo02.jpg" }, { thum_class : ".img_03", image_url : "images/photo03.jpg" } ] // ページ読み込み完了時の処理 $(function(){ // pictures[_].thum_classのクラスの要素にclick()を設定 for (var i = 0; i < pictures.length; ++i) { $( pictures[i].thum_class ).click( pictures[i], function(e){ ChangePicture(e.data); }); } // 画像読み込み完了時のイベントを設定 $('#load_image').bind('load', function() { // ロードインジケーターを非表示化 $('#image_view #indicator').animate({ opacity:0 }, 'normal', 'swing', function() { $('#image_view #indicator').hide(); }); }); }); // 画像を切り替える関数 function ChangePicture(picture_data){ // ダミーのImageを作ってひとまずUrlを設定 var _img = new Image() ; _img.src = picture_data.image_url; // 画像URLをimgに反映 $('#load_image').attr( 'src', _img.src ); // ダミーのImageの方で既に読み込まれているかどうか確認 if ( _img.complete == false ) { // 読み込まれていない場合にロードインジケーターを表示 $('#image_view #indicator').show(); $('#image_view #indicator').css({ opacity: 1 }); } }
一応ですが、画像キャッシュの確認部分、無くても動きそうな感じではあります。
参考サイト
所感
細かいところの作り込みが、良いUIにしていくんですよねおそらく。
でもこういうのはやり出すと止まらなくなる面もあったり。
※2018/10/20 コード、及び、文章の一部を修正しました。
※2018/10/20(2) IEでの表示に問題が在りましたので一部コードを修正しました。
コメントはありません。