POPSブログ

jQuery 非同期、Imageオブジェクトで複数画像を読み込む

357

  Category:  jquery2015/05/12 pops 

非同期に画像1枚ではなく、複数画像を読み込む方法である。プラグインなどを使用する方法もあるが、JavaScriptのImageオブジェクトで1枚づつ読み込んだ方が応用性に富むと思います。マシンも最近高速ですから読み込みも結構早いし簡単に記述できます。「1枚づつ読み込む方法」と「同時に読み込む方法」の2つをテストします。

 

jQuery 非同期、Imageオブジェクトで複数画像を読み込む、テスト


実際には、非同期で複数画像を読み込むことは稀と思いますから、ほとんど利用価値が無いとも予想されます。
最近、クロスドメイン画像の読み込みなどが Security の関係で制約されることが多いので、CreateJS用に作ったものを再利用するものです。クロスドメイン画像が読み込めますから、使用する機会もあるかも知れません。

 

zu-da

 

 

Imageオブジェクトで画像を読み込む理由


jQuery処理で画像を読み込む方法は色々とありますが、「Imageオブジェクトで画像を読み込む」最大の利点は、簡単に「画像の大きさが取得」出来ることに有ります。時として「画像の大きさ」が判らないと処理出来ない状況もあります。


1. 記述が簡単で使い易く読み込みも早い。
2. エラー処理が出来る。
3. 画像の大きさが取得できる。
4. クロスドメイン画像が読み込めます。
5. 特別な理由がある場合。


new Image() の正体

document.createElement('img') と同じですが、new Image() と書けると言うことだけです。
htmlにappendしない場合はメモリー上の処理になり、「読み込み済み画像」はブラウザに「キャッシュ」されますから、後で利用できることになります。
● 画像URLで保存したほうが、後で使い易いのでここでは「画像URL」を保存します。


var img=new Image();
上と下は同じです
var img=document.createElement('img');

オブジェクトに onload onerror 等のイベントを付加できるので
var img=new Image();
img.onload=function(){
	//処理
};
img.src="画像URL";

と成る

● 保存画像URLで画像を表示する。divに収容した方が何かと便利です。


空画像の構造があれば
<div id="top-image-box"><img /></div>

次の処理で画像を表示できる、ここではキャッシュがあるので瞬時に表示する
$('#top-image-box').children("img").attr({'src':保存画像URL});

画像を取り替えるなら、別の保存画像URLを入れれば、階層(z-index)が変わること無く瞬時に表示できる
$('#top-image-box').children("img").attr({'src':別の保存画像URL});

DEMO Imageオブジェクトで複数画像を読み込む

● デモページは [ jqury-1.9 ] で動作しています。JS、CSS、は「デモ」ページに掲載しています。


DEMO1、画像1枚づつ読み込む形式 (推奨)

DEMO-015

このデモの説明: 簡単な説明 1


DEMO2、ほぼ同時に複数画像を読み込む形式 (非推奨)

DEMO-015b

このデモの説明: 簡単な説明 2




 

HTMLでの通常の画像表示 (参考表示)


通常のHTMLでの画像表示は<img />を羅列すれば「読み込み表示」しますから、特別にローダーを利用せずとも良い訳です。仮に縮小させてサムネールを表示しても、大きな元の画像はブラウザにキャッシュされていますので即座に表示可能です。


下記の「デモ」ではサムネールを画像縮尺して表示して、同じ画像URLで大きな画像を表示しています。通常はローダーなど使用しません。直接imgタグで表示するのが一般的です。


AUTOスライドショー、サムネール「クリック」で該当画像表示。(フエードアニメ中はクリックが機能しません、jquery-1.6.4)

 

WELCOME

極一般的な表示ですから、説明などは省略します。(2番目は省スペース縦列駐車です)

 

HTML5、Canvasでの画像表示


Canvasでの画像表示の場合は、「完全読み込み済み」の画像を使用しなければなりません。
またクロスドメイン画像は原則表示出来ません。(但し表示する方法はあるが、色々と悪影響が出る)

原則、画像ローダーなどで読み込み完了後に処理する事になります。


 

簡単な説明


簡単な説明 1

 

Imageオブジェクトで複数画像を非同期に画像1枚づつ読み込む方法で、エラー画像は読み込まない事にする。
最近のマシン環境が良いので、ストレス無く読み込める。結構早いので十分に実用性があると思います。


1. 画像URLリストの画像数と読み込みカウントの比較で終了させるだけ。
2. エラー処理はprogressのためにカウントUPのみ。(必要ならば修正可能)
3. 画像の大きさが簡単に取得できる。(但しこのデモでは未使用)
4. LoadingをJSタイプにしてみました。透過するので綺麗です。(spin.js)
5. ProgressBar描画は読み込みがわかる程度の簡単なものです。


繰り返し処理部分

画像分、処理を繰り返しているだけです。対処できないエラーもあるが通常はこれで間に合うと思う。
説明せずとも見れば判ると思います。



		//画像マルチローダー1
		function multiLoader() {

			//ProgressBar描画
			progress(imageload_count/loadImage_len);

			//画像Load終了判定
			if(imageload_count < loadImage_len) {
				//読み込み
				getLoadImage();
			} else {
				//終了
				multicomplete();
			}
		}

		//new Image()の実行
		function getLoadImage() {

			//new Loader
			var image_loader=new Image();
			image_loader.onload=function() {

				//読み込みOK
				//サムネール大きさ取得
				loadimg_W.push(image_loader.width);
				loadimg_H.push(image_loader.height);
				//サムネールURL保存
				assets_url.push(imagelist[imageload_count]);
				//次画像のロード
				imageload_count ++;
				multiLoader();
			}
			image_loader.onerror=function() {

				//カウントアップのみ
				imageload_count ++;
				multiLoader();
			}
			//URL
			image_loader.src=imagelist[imageload_count];
		}


Loading

● 今回から、必要があればspin.jsを使用する事にします。
設定も簡単で、JSさえ読み込んでおけば使用できます。

面倒な場合は従来通りアニメGIFなど使用すればよいし、最近はCSSでのLoadingも増えています。


JSのダウンロードと説明テストなどは、下記配布先サイトで。

【DL】配布先: spin.js

JSの設定などは下記サイトの記事が参考になります。

【参考】kantenna.comの記事: spin.js



//#loading-boxにspinnerセット
set_spinner('loading-box');

-------------------------------------------------------
//spinner
function set_spinner(item){
	var opts={lines:12,length:4,width:3,radius:8,corners:1,color:'#CCCCCC',shadow:false};
	var target=document.getElementById(item);
	var spinner=new Spinner(opts).spin(target);
}

● 従来通りのGIF画像を使用する場合


#loading-box{
background:url("/main/images/loading.gif") no-repeat center center;
}

loading-daze

 

簡単な説明 2

 

このJSは、[stackoverflow] http://stackoverflow.com/questions/476679/preloading-images-with-jquery の記事を参考に作成しました。イワユル「パクリ」で有ります。

【参照】stackoverflow.com: Preloading images with jQuery


Imageオブジェクトで複数画像を非同期に同時に読み込む方法で、上記と同じにエラー画像は読み込まない事にする。
最近のマシン環境が良いので、問題が出ることは少ないと思いますが、処理の特殊性から不都合が出る可能性は残ります


1. 無名関数の特性を利用しています。(実行は1回限り)
2. エラー処理が完全で無いと途中で無名関数から抜け出られない。(停止同様になる)
3. 簡単に複数画像を非同期に同時に読み込む事が可能。(これは感心する)
4. LoadingをJSタイプにしてみました。(spin.js使用)
5. ProgressBar描画は読み込みが判る程度の簡単なものです。(エラーを考慮していない)


処理の問題点.....

簡単に読み込めるのは利点であるが、反面、処理の特殊性から非常にエラー処理が難しいと思います。


1. 関数 preloadPictures を先に記述して、その後に実行させます。
2. 読み込みエラーが発生すると無名関数から抜け出られないので、読み込み中断時の処理をする.onabortを加える。
(正常に機能するか不明、通信が途切れて「途切れました」の連絡は来るのか...疑問だ)
3. 無名関数から抜け出るには何らかの関数で処理できるように仕組む。(難しい)
4.有る程度の時間経過で「読み込み」を打ち切ることも必要でショウ(デモでは未処理です)


下記の様に修正して動作させています。Flickr画像などをも表示テスト(サムネール取得だが驚くほど早い)しましたが、今時点では問題はでていません。
問題が出る場合は、自己解決ください。またプラグインを利用するのも方法でしょう。



//同時複数読み込みローダー/順不動
var preloadPictures=function(pictureUrls,callback){

	var i,j,loaded=0;
	var urls=[];
	var count=0;

	for(i=0,j=pictureUrls.length;i<j;i++){

		(function(img,src){

			img.id=i;
			img.onload=function(){

				var id=img.id;

 				//URL取得保存
				//urls.push(img.src);//順不動
				urls[id]=img.src;//順不動を補正

				//progressBar
				progress(count/pictureUrls.length);

				if(++loaded == pictureUrls.length && callback){
					callback(urls);
				}
				count ++;

			};
			img.onerror=function(){
				if(++loaded == pictureUrls.length && callback){
					callback(urls);
				}
			};
			img.onabort=function(){
				if(++loaded == pictureUrls.length && callback){
					callback(urls);
				}
			};

			img.src=src;

		}(new Image(),pictureUrls[i]));

	}
};

//bulk-load、画像一括ロード
function bulkload() {

	略す

	//同時複数読み込みローダー実行
	imageload_count=0;
	preloadPictures(imagelist,multicomplete);

}

● 順不動になりますので、エラー時の配列を削除して、画像リスト順に並べ替えます。
当方では画像URLを取得して処理する事が多い。この辺の処理方法は幾つもあるでしょう。



//全ての画像読み込み完了
function multicomplete(urls) {

	//配列整理
	for (var i=0; i < urls.length; i++) {
		if(urls[i]) {assets_url.push(urls[i]);}
	}

	略す

}

クロスドメイン画像などについて

最近、Security の観点からクロスドメイン画像および各種ファイルなど読み込みに規制が有り、ライブラリなどもその様な傾向にあり、順次バージョンアップ毎にクロスドメインファイル等読み込み難く対処されています。
自分のサイトの画像なら問題はないでショウが(判りませんが...)、Image()オブジェクトは簡単に画像を読み込めますので、クロスドメイン画像は危険が危ない、よって信頼の於ける所よりLOADください。


参照、参考

基本的な非同期、Imageオブジェクトで複数画像を読み込む方法などは、下記記事を参照ください。

【参照】当方の記事: jQuery非同期、Image()で画像読み込み表示


画像

サンプル画像 / 原則 使用者が用途に応じてご用意ください。デモページより取得できます。

 

以上です。

 


[ この記事のURL ]


タグ:jquery , SlideShow

 

ブログ記事一覧

年別アーカイブ一覧



[1]