私は、ユーザーが URL を入力し、URL から画像を抽出できるようにする Web ページを作成しています。Facebook や pinterest や thefancy.com のようなものです。URL を入力すると、指定された幅より大きい幅の画像が取得されます。
私のコードはすべて jQuery であり、この画像サイズの決定と正常に動作するという要件はありませんでした。また、私の JavaScript の知識はかなり限られています。
ユーザーが Enter キーを押すと、ページは (jQuery を使用して) ajax 要求をサーバー側スクリプトに発行し、ページから抽出された画像ソースの配列を含む json オブジェクトを受け取ります。ajax.success コールバック内で、この画像の配列を、jquery append() メソッドを使用して DIV に画像を動的に追加するメソッドに渡します。
// server script errors are also reported inside
// ajax success callback
success: function(response){
switch(response.code) {
case 401 :
webgloo.sc.ImageSelector.showMessage(response.message,{"css":"color-red"});
break ;
case 200 :
webgloo.sc.ImageSelector.processUrlFetch(response);
break ;
default:
webgloo.sc.ImageSelector.showMessage(response.message,{"css":"color-red"});
break ;
}
},
成功のコールバック ハンドラ内で画像サイズを取得しようとして立ち往生しています。SO を読んだ後、画像ロード ハンドラーを追加し、その画像ロード ハンドラー内に、num_added 変数をインクリメントするコールバック addImage() を用意しました。後で、この num_added 変数を使用して、ユーザーに表示するメッセージの種類を決定したいと考えています。
問題は、showNextMessage() が processUrlFetch() でループが完了するのを待たないことです。showNextMessage() は、processUrlFetch() が呼び出されるとすぐに起動されます。したがって、常に「画像が見つかりません」というメッセージが表示されます。
私はこのトピックを調査しようとしましたが、ここでは深みがありません。jquery と DOM イベントを混在させることが問題になる可能性があると思います。また、 image.load() を介して画像サイズを取得する方法論がどの程度防弾であるかはわかりません。また、imagesloaded プラグインが私の目的に役立つかどうかもわかりません。
2つの質問があります
- ここで動的に挿入された画像の「実際の」画像サイズを取得するために行っていることが、有効なクロスブラウザー手法である場合 (img.load イベントに依存)
- ループが終了した後にのみ showNextMessage() が起動されるようにするにはどうすればよいですか?
processesUrlFetch : function(response) { var images = response.images ;
for(i = 0 ; i < images.length ; i++) {
var img = new Image();
/* trouble part */
img.onload = function() {
if((this.width >= 300) && (this.height >= 300 )) {
webgloo.sc.ImageSelector.addImage(this.src);
}
}
img.src = images[i] ;
webgloo.imagep.src = images[i] ;
}
webgloo.sc.ImageSelector.showNextMessage();
},
showNextMessage : function() {
if(webgloo.sc.ImageSelector.num_added > 0 ) {
$("#stack").fadeIn("slow");
$("#next-message").fadeIn("slow");
} else {
var message = "No image of appropriate size found!";
webgloo.sc.ImageSelector.showMessage(message, {"css":"color-red comment-text"});
}
},
addImage : function(image) {
webgloo.sc.ImageSelector.num_added++ ;
var index = webgloo.sc.ImageSelector.num_added ;
if(webgloo.sc.ImageSelector.debug) {
console.log("Adding image : " + index + " : " + image);
}
var buffer = this.imageDiv.supplant({"srcImage":image, "id":index } );
// logo, small icons etc. are first images in a page
// what we are interested in will only come later.
$("div#stack .images").prepend(buffer);
this.bucket[index] = { "id":index, "srcImage": image, "selected" : false} ;
},
完全なコードを見たい場合 - ここに要点があります: - https://gist.github.com/3084904