93cracker93: Javascript Vorschau mit Bild

Also ich möchte ein Vorschau+Bildvorschau haben.
Durch das erste thumbnail2 wird wenn ein Benutzer ein Bild auswählt automatisch eine Vorschau erststellt. Bloß das Problem ist, dass im Formular noch mehr sachen stehen sollen später und wenn ich dann auf den Button Vorschau drücke,dann lädt die Seite neu und die Vorschau ist wieder weg. Deswegen habe ich die img.src in den Storage geschrieben, sobald ein bild ausgewählt wird. Und wenn man auf Submit klickt soll sie aus dem Storage wieder herausgelesen werden und als thumbnail3 oben angezeigt werden. Dies klappt aber nicht, Es wird mir erst gar kein Bild nach Buttondrücken ausgegeben. Und komme nicht weiter, vllt entdeckt ihr ja einen Fehler den ich gemacht habe.

<form id="bbcode2" method="post" enctype="multipart/form-data" >  
    <div id="thumbnail3"></div>  
    <input type="file" name="hauptbild" id="hauptbild" onChange="fileThumbnail2(this.files);" accept="image/*" multiple /><div id="thumbnail2"></div>  
  <input type="submit" name="Vorschau" value="Vorschau" onclick="fileThumbnail3(this.files);" />  
</form>
<script type="text/javascript">  
  
window.URL = window.URL || window.webkitURL;  
function fileThumbnail2(files)  
{  
  
  var thumb = document.getElementById("thumbnail2");  
  
  thumb.innerHTML = "";  
  
  if(!files)  
    return;  
  
  for(var i = 0; i < files.length; i++)  
  {  
    var file = files[i];  
  
    if(!file.type.match(/image.*/))  
      continue;  
  
    var img = document.createElement("img");  
  
         img.src = window.URL.createObjectURL(file);  
         localStorage.setItem("bla", img.src);  
  
    img.width = 620;  
  
    img.onload = function(e) {  
      window.URL.revokeObjectURL(this.src);  
    };  
  
  
                thumb.appendChild(img);  
  }  
}  
  
window.URL = window.URL || window.webkitURL;  
  
function fileThumbnail3(files)  
{  
  
  var thumb = document.getElementById("thumbnail3");  
  
  thumb.innerHTML = "";  
  
  if(!files)  
    return;  
  
  for(var i = 0; i < files.length; i++)  
  {  
    var file = files[i];  
  
    if(!file.type.match(/image.*/))  
      continue;  
  
    var img = document.createElement("img");  
  
   img.src = localStorage.getItem("bla");  
  
  
    img.width = 620;  
  
    img.onload = function(e) {  
      window.URL.revokeObjectURL(this.src);  
    };  
  
  
                thumb.appendChild(img);  
  }  
}

Ich bitte um Hilfe, Grüße

  1. Hallo,

    Dein Code scheint einiges zu verdoppeln und durcheinander zu bringen, daher habe ihn für mein Verständnis einmal aufbereitet (http://jsfiddle.net/molily/LRGdg/). Ich habe die revokeObjectURL-Aufrue entfernt, das sollte man natürlich nicht tun, wenn man sie später noch einmal wiederverwenden will.

    window.URL.createObjectURL erzeugt ein Objekt, »whose lifetime is tied to the document in the window on which it was created« (MDN).

    Das bedeutet m.E., dass es nicht im localStorage abgespeichert werden kann. Denn der Sinn von localStorage ist, Daten zwischen window-Kontexten zu teilen, also Daten über einen Seiten-Wechsel bzw. -Reload zu persistieren.

    Beim Aufruf von localStorage.setItem() wirft obiges Script im Chrome eine Security-Exception. Im Firefox und Safari funktioniert es interessanterweise, auch über einen Reload hinaus!

    Bloß das Problem ist, dass im Formular noch mehr sachen stehen sollen später und wenn ich dann auf den Button Vorschau drücke,dann lädt die Seite neu und die Vorschau ist wieder weg.

    Dann sorge dafür, dass kein Seitenwechsel stattfindet, z.B. indem du das Formular per Ajax absendest oder es ein verstecktes Iframe als target hat. Dann kannst du die Bild-URLs einfach irgendwo in einer Variablen/Objekteigenschaft speichern und wiederverwenden.

    Allgemein verwendet man wegen solchen Problemen Single-Page-Apps, führt also keine oder nur wenige Seitenwechsel durch. Dadurch bleiben die JavaScript-Objekte, die man einmal aufgebaut hat, im Speicher. Das ist natürlich besonders bei Dateien nützlich, die der Nutzer über <input type="file"> ausgewählt hat.

    Eine Alternativmöglichkeit wäre, das Bild über die File-API als Data-URI auszulesen und diese Data-URI im localStorage abzuspeichern. Allerdings bekommt man dann die Bilddaten Base64-kodiert in einem String, und der kann riesig sein. Das Abspeichern im localStorage ist möglich, aber je nach Bildgröße und Dateianzahl ist das Limit schnell erreicht. Darüber wirst du vermutlich schon hinaus sein und hast aus Gründen zu createObjectURL gegriffen...?

    Mathias

    1. Wow, danke. Ja ich bemerke auch gerade die Dopplungen. Genauso wie bei deinem Script habe ich es mir vorgestellt. Aber wie mache ich das jetzt, wenn da noch ein zusätzlicher input text ist?

      Also zb im Formular:

      Name:<input type="text" name="name" maxlength="20" id="name" />

      Den kann ich in der Vorschau dann ja nicht einfach via Print $_post aufrufen.

      1. Daher das meine Fragestellung oben ziemlich komisch formuliert war, schreib ich hier nochmaal genauer.

        Also ich habe einmal das Bild und ein Textfeld name. Das möchte ich aber nur anzeigen wenn der Button gedrückt wurde. Das heißt wenn ich oben in der Vorschau:

        Hier steht der Name: <p id="name"></p>  
        Hier ist das Bild: <p id="output2"></p>
        

        schreibe und darunter die Formular Box, dann wird "Hier steht der Name:" von Anfang an auf der Seite angezeigt, obwohl die gesamte vorschau erst angezeigt werden soll, wenn Button geklickt wurde.

        Bitte um Hilfe.