2017-01-16 49 views
0

我有一個循環的小問題。我正在構建一個小工具,用戶必須上傳12個圖像。圖像被裁剪成矩形並放置在按鈕上。我差不多已經準備好了,但不知怎的,循環不能正常工作。所有圖像都落在最後一個按鈕上。這裏的循環可能有問題嗎?循環:圖像僅落在最後一個字段

JS/JQuery的:

for (var i = 0; i < 12; i++) { 
    var j=i+1; 
    var reader = new FileReader(); 
    reader.onload = function (e) { 
     var img = new Image(); 
     img.src = e.target.result; 

     img.onload = function() { 

      var getimage= '#getimage'+j; 

      // CREATE A CANVAS ELEMENT AND ASSIGN THE IMAGES TO IT. 
      var canvas = document.createElement("canvas"); 

      var ctx = canvas.getContext("2d"); 
      ctx.clearRect(0, 0, canvas.width, canvas.height) 
      var posh, posw; 
      var factheight=img.height; 
      var factwidth=img.width; 
      if(factwidth<factheight){ 
       canvas.width = img.width; 
       canvas.height= img.width; 
       posh=(img.height-img.width)/2; 
       posw=0; 
      } 
      else if(factheight<factwidth){ 

       canvas.height = img.height; 
       canvas.width = img.height; 
       posh=0; 
       posw=(img.width-img.height)/2; 
      } 
      else{ 
       canvas.width = img.width; 
       canvas.height= img.height; 
       posh=0; 
       posw=0; 
      } 
      ctx.drawImage(img, posw, posh, canvas.width, canvas.height, 0, 0, canvas.width, canvas.height); 

      var cropped=canvas.toDataURL("image/png"); 

      $(getimage).attr("src",cropped);  // SHOW THE IMAGES OF THE BROWSER. 
     } 
    } 

    reader.readAsDataURL($('.multiupload')[0].files[i]); 

} 

這裏也是到JSFiddle的鏈接。感謝您的幫助,因爲我不知道究竟是如何reader.readAsDataURL($('.multiupload')[0].files[i]);target.result工作

+1

的可能的複製[JavaScript的閉包內環路 - 簡單實用的例子(http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example) – Teemu

+0

你可以用」在內部使用j。因爲onload將在循環結束後被調用(因爲它是回調 - 異步函數)。每個onload函數調用將有j = 12。 onload =(function(j){return function(){...您的代碼}})(j)可以幫助您。 也許有人會完成我的想法..h –

+0

在onload函數的第一行添加'var img = this;'會得到正確的圖像。但是onload函數的最後一行將不會像上面提到的那樣工作j將會有錯誤的值。 – Blindman67

回答

1

我猜,你的循環結束之前,任何圖像滿載所以j將是11前的用來尋找相關按鈕。嘗試改變

img.onload = function() { .... }

img.onload = myFunction(id)

然後移動所有的東西內聯函數到其自身的功能與輸入參數。然後通過j作爲id參數。

+0

感謝您的回答。是的,圖像加載非常緩慢,但由於我在後臺使用裁剪器,速度不會很快。你知道我怎麼可以應用一個加載圖像,直到圖像完全加載? – PLAYCUBE

+1

在這裏,你去。 https://jsfiddle.net/53aesgep/2/ 只要在'j'爲11(或圖像最大數量)時調用hideLoader – cspete

1

我已經爲你做了一個例子。正如我回答評論

var reader = new FileReader(); 
reader.onload = (function(j){return function (e) { 
var img = new Image(); 
... 

https://jsfiddle.net/ykze3f9r/

+0

謝謝!我只是設法這樣做'var funcs = [];函數multicrop(i){...}'和'for(var i = 0; i <6; i ++)funcs [i] = multicrop(i); }' 兩種方式都不錯嗎? – PLAYCUBE

+0

它的工作原理,我同意。但看起來不是很優雅。這是你的實現 - 所以它是最好的) –

1

與代碼的主要問題是j變量。由於for循環的工作方式,它始終設置爲最後一個數字。您必須改爲綁定該號碼。我分解成單獨的函數以使其更易於閱讀。這裏的工作JSFiddler:https://jsfiddle.net/eh6pr7ee/2/

處理圖像...

var processImg = function(img, imgNum) { 
    var getimage= '#getimage' + imgNum; 
    // CREATE A CANVAS ELEMENT AND ASSIGN THE IMAGES TO IT. 
    var canvas = document.createElement("canvas"); 

    var ctx = canvas.getContext("2d"); 
    ctx.clearRect(0, 0, canvas.width, canvas.height) 
    var posh, posw; 
    var factheight = img.height; 
    var factwidth = img.width; 
    if (factwidth < factheight) { 
    canvas.width = img.width; 
    canvas.height = img.width; 
    posh = (img.height-img.width)/2; 
    posw = 0; 
    } 
    else if (factheight < factwidth) { 
    canvas.height = img.height; 
    canvas.width = img.height; 
    posh = 0; 
    posw = (img.width-img.height)/2; 
    } 
    else { 
    canvas.width = img.width; 
    canvas.height= img.height; 
    posh = 0; 
    posw = 0; 
    } 
    ctx.drawImage(img, posw, posh, canvas.width, canvas.height, 0, 0, canvas.width, canvas.height); 
    var cropped = canvas.toDataURL("image/png"); 
    $(getimage).attr("src",cropped); // SHOW THE IMAGES OF THE BROWSER. 
}; 

創建圖像,並且將源...

var setImage = function(imgNum, e) { 
    var img = new Image(); 
    img.src = e.target.result; 
    img.onload = processImg.bind(this, img, imgNum); 
}; 

創建圖片上傳的處理函數...

var handleImageUploads = function() { 
    if (parseInt($(this).get(0).files.length) > 12 || parseInt($(this).get(0).files.length) < 12) { 
    alert("Please upload 12 photos"); 
    } 
    else { 
    //loop for each file selected for uploaded. 
    for (var i = 0; i < 12; i++) { 
     var reader = new FileReader(); 
     reader.onload = setImage.bind(this, i+1); 
     reader.readAsDataURL($('.multiupload')[0].files[i]); 
    } // for 
    console.log("done"); 
    $('body').removeClass("loading"); 
    }; // else 
} 

綁定處理函數。

$('.multiupload').on("change", handleImageUploads); 
相關問題