2016-06-19 10 views
1

ajax関数を介して返されたパスのリスト(10個のアイテム)からイメージを読み込み、それぞれのサイズを変更してからページを表示します。しかし、以下のコードは最初の画像(サイズ変更された画像)のみを表示し、他の画像は表示しません。印刷されたサイズが正しく見えるので、サイズ変更がうまく動作することは間違いありません。 JavaScriptのコードは以下のとおりです。JavaScriptでイメージのサイズを変更して表示するには

// Helper function 
function scaleSize(maxW, maxH, currW, currH){ 
    var ratio = currH/currW; 
    if(currW >= maxW && ratio <= 1) { 
     currW = maxW; 
     currH = currW * ratio; 
    } else if(currH >= maxH) { 
     currH = maxH; 
     currW = currH/ratio; 
    } 
    return [currW, currH]; 
} 

function get_similar_images(image_name) { 
    console.log(image_name) 
    $.ajax({ 
     type: "POST", 
     contentType: "application/json; charset=utf-8", 
     url: "/get_similar", 
     dataType: "json", 
     async: true, 
     data: JSON.stringify({name: image_name}), 
     success: function(data) { 
      console.log(data); 
      image_list = data['images'] 
      category = data['category'] 
      for (var i=0; i<image_list.length; i++) { 
       var img = document.createElement("img"); 
       img.src = "static/products/"+category+"/"+image_list[i]; 
       var actualH; 
       var actualW; 
       var newH; 
       var newW; 
       img.onload = function(){ 
        actualW = this.width; 
        actualH = this.height; 
        console.log(actualW, actualH) 
        var newSize = scaleSize(300, 300, actualW, actualH); 
        console.log(newSize) 
        img.width = newSize[0]; 
        img.height = newSize[1]; 
        document.getElementById('imageDiv').appendChild(img) 
       }; 
      } 
     }, 
     error: function(xhr, status, error) { 
      // console.log(xhr.responseText); 
     } 
    }) 
} 
+0

はSOへようこそ!まず、あなたの 'image_list.length'は1より大きいですか? –

+0

はい、これは10項目です – Melanie

+0

そして 'newSize'を記録すると、期待値(幅と高さが300以下)がありますか? –

答えて

0

我々はそのようなあなたのforループを簡素化した場合:

var img = document.createElement("img"); 
img.src = image_list[0]; 
img.onload = function() { 
    console.log(img); 
}; 

var img = document.createElement("img"); 
img.src = image_list[1]; 
img.onload = function() { 
    console.log(img); 
}; 

あなたの間違いはどこから来るあなたが理解するだろう。 onloadはイベントです。つまり、あなたのコードから非同期で実行されています。最初のloadイベントがトリガーされる前に、新しいイメージ要素(および新しいhref属性)でimg値を更新しています。したがってonloadイベントは実際にはの最後のループに到達したときに実際に発生するimg変数の最終更新後に呼び出されます。

なぜですか?

forループは変数imgのための新しいスコープを作成しませんので、あなたが前にvarを入れている場合でも、それぞれの時間は、あなたが、img VARに触れているので、オリジナルのimgが更新されます。関数が実際に宣言された変数のための新しいスコープを作成するため

あなたはそれの内側に、(var myVar)の機能を使用する必要があります。

function injectAndResize(imageUrl) { 
    var img = document.createElement("img"); 
    img.src = imageUrl; 
    var actualH; 
    var actualW; 
    var newH; 
    var newW; 
    img.onload = function() { 
    actualW = this.width; 
    actualH = this.height; 
    var newSize = scaleSize(300, 300, actualW, actualH); 
    this.width = newSize[0]; 
    this.height = newSize[1]; 
    document.getElementById('imageDiv').appendChild(img); 
    }; 
} 

for (var i = 0; i < image_list.length; i++) { 
    injectAndResize(image_list[i]); 
} 
+0

これはうまくいきました!あなたの助けに! – Melanie

+0

あなたは大歓迎です^^ –

0

コードにはいくつか問題があります。
1)画像の幅と高さはCSSプロパティで、ハンドラではundefinedとなる場合があります。代わりにthis.naturalWidthを使用してください。
2)img.src = 'url';がイメージの読み込みをトリガーします。img.onloadの後にと置きます。

success: function(data) { 
     console.log(data); 
     image_list = data.images; 
     category = data.category; 
     for (var i=0; i<image_list.length; i++) { 
      var img = document.createElement("img"); 
      img.onload = function(){ 
       var actualW = this.naturalWidth; 
       var actualH = this.naturalHeight; 
       console.log(actualW, actualH) 
       var newSize = scaleSize(300, 300, actualW, actualH); 
       console.log(newSize) 
       this.width = newSize[0]; 
       this.height = newSize[1]; 
       //also think what to do with images which are already there 
       //probably remove 
       document.getElementById('imageDiv').appendChild(this) 
      };//img.onload 
      img.src = "static/products/"+category+"/"+image_list[i]; 
     }//for 
    },//success 
関連する問題