2017-01-16 3 views
0

Ich habe ein kleines Problem mit einer Schleife. Ich baue ein kleines Werkzeug, wo ein Benutzer 12 Bilder hochladen muss. Die Bilder werden in Rechtecken zugeschnitten und auf Schaltflächen platziert. Ich bin fast fertig, aber irgendwie funktioniert die Schleife nicht gut. Alle Bilder landen auf dem letzten Knopf. Vielleicht stimmt hier was nicht?Schleife: Bilder landen nur auf dem letzten Feld

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]); 

} 

Hier ist auch ein Link auf die JSFiddle. Schätzen Sie Ihre Hilfe, da ich nicht genau weiß, wie reader.readAsDataURL($('.multiupload')[0].files[i]); und target.result

+1

Mögliche Duplikat [JavaScript-Verschluss Innenschleifen - einfaches praktisches Beispiel] (http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example) – Teemu

+0

Sie können‘ t j in onload verwenden. Weil onload aufgerufen wird, nachdem die Schleife beendet wurde (wie es Callback ist - Async-Funktion). Jeder Onload-Funktionsaufruf hat j = 12. onload = (Funktion (j) {return function() {... Ihr Code}}) (j) kann Ihnen helfen. Vielleicht wird jemand meine Gedanken beenden.h –

+0

In der ersten Zeile der Onload-Funktion hinzufügen 'var img = this;' wird das richtige Bild bekommen. Die letzte Zeile der Onload-Funktion funktioniert jedoch nicht wie oben erwähnt. J hat den falschen Wert. – Blindman67

Antwort

1

arbeitet Ich vermute, dass Ihre Schleife beendet ist, bevor Sie die Bilder vollständig geladen werden, so j 11 sein wird, bevor seine verwendet, um die entsprechende Taste finden . Versuchen

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

zu

img.onload = myFunction(id)

Dann ist alles aus der Inline-Funktion in seine eigene Funktion mit einem Eingabeparameter zu ändern bewegen. Dann übergeben Sie j als id param.

+0

Danke für Ihre Antwort. Ja, die Bilder werden sehr langsam geladen, aber da ich den Cropper im Hintergrund benutze, wird er nicht schnell sein. Weißt du, wie ich ein Ladebild anwenden kann, bis die Bilder vollständig geladen sind? – PLAYCUBE

+1

Hier gehen Sie. https://jsfiddle.net/53aesgep/2/ Gerade hideLoader rufen, wenn 'J' 11 (oder Sie maximale Anzahl der Bilder) – cspete

1

Ich habe ein Beispiel für Sie gemacht. Wie ich in den Kommentaren

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

https://jsfiddle.net/ykze3f9r/

+0

Thank you! Ich habe es einfach geschafft, das zu tun. 'Var funcs = []; Funktion Multicrop (i) {...} 'und' für (var i = 0; i <6; i ++) { funcs [i] = Multicrop (i); } ' Ist so oder so gut? – PLAYCUBE

+0

Es funktioniert, ich stimme zu. Aber sieht nicht sehr elegant aus. Das ist deine Implementierung - also ist es das Beste –

1

Das Hauptproblem mit dem Code war die j Variable. Es wurde immer auf die letzte Nummer eingestellt, weil die for Loops funktionieren. Sie müssen stattdessen diese Nummer binden. Ich habe getrennte Funktionen eingerichtet, um das Lesen zu erleichtern. Hier ist der Arbeits JSFiddler: https://jsfiddle.net/eh6pr7ee/2/

Verarbeitet das Bild ...

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. 
}; 

Bild erstellt und Quelle setzt ...

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

eine Handler-Funktion erstellen für Bild-Uploads ...

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 
} 

Bindet die Handler-Funktion.

$('.multiupload').on("change", handleImageUploads); 
Verwandte Themen