Javascript come vedere in anteprima le foto caricate nel input file prima di mandarle al server

Stato
Discussione chiusa ad ulteriori risposte.

coronel

Utente Gold
28 Agosto 2017
455
111
32
254
vorrei poter avere un anteprima in miniatura delle foto che carico sul input file ma non trovo il modo, ho provato a recuperare il value del input file x poi inserirlo dentro un src di un anchor ma la path non e quella della foto ma una path che comincia con fakepath, e quindi non funziona, il progetto trattasi di un marketplace del usato con vari filtri, di vestiti e di scarpe, se volete continuare il progetto vi lascio qui il codice sorgente


Vedi: https://pastebin.com/6ZF0f7cJ
 
Ultima modifica:
Ciao!

HTML, div galleria e file input:
HTML:
<input type="file" name="file" id="file_input">
<div id="galleria">
    <img id="preview" src="" alt="preview" />
</div>

JavaScript, per visualizzare la preview:
JavaScript:
const imgInput = document.getElementById('file_input');
imgInput.addEventListener("change", (e) => {
  const [file] = imgInput.files;
  if (file) {
    document.getElementById('preview').src = URL.createObjectURL(file);
  }
})

Puoi adattare la soluzione alle tue esigenze, come vedi la soluzione è VJS ma puoi anche decidere di usare JQuery.
 
  • Mi piace
Reazioni: JunkCoder
Ultima modifica:
Ciao!

HTML, div galleria e file input:
HTML:
<input type="file" name="file" id="file_input">
<div id="galleria">
    <img id="preview" src="" alt="preview" />
</div>

JavaScript, per visualizzare la preview:
JavaScript:
var imgInput = document.getElementById('file_input');
imgInput.addEventListener("change", (e) => {
  const [file] = imgInput.files
  if (file) {
    document.getElementById('preview').src = URL.createObjectURL(file);
  }
})

Puoi adattare la soluzione alle tue esigenze, come vedi la soluzione è VJS ma puoi anche decidere di usare JQuery.
scusami ma perche assegni una funzione con parametro e se gia c'e l'evento change che va parte ogni volta che premo il pulsante x caricare il file? e poi non mi e chiaro perche dichiari una variabile con le parentesi quadre tipo java var x [] = valore
tra l'altro mi hanno consigliato di usare l 'attributo multiple nel tag input file, altri di impostare un name con le [] e sono un po confuso.. aproposito quello che ecmascript e?
 
scusami ma perche assegni una funzione con parametro e se gia c'e l'evento change che va parte ogni volta che premo il pulsante x caricare il file? e poi non mi e chiaro perche dichiari una variabile con le parentesi quadre tipo java var x [] = valore
tra l'altro mi hanno consigliato di usare l 'attributo multiple nel tag input file, altri di impostare un name con le [] e sono un po confuso.. aproposito quello che ecmascript e?
Ciao,
onestamente ho guardato la logica che avevi scritto e non mi era chiarissima, inoltre ai fini di quello che chiedevi non era rilevante, quello che ho postato riguarda solo e soltanto la preview di un'immagine caricata.

La "dichiarazione" (assegnazione) che menzioni si chiama Destructuring Assignment, ti lascio la referenza per capire meglio di cosa si tratta.

Per l'input dipende da quello che vuoi fare -- il multiple attribute ti permette di selezionare più file insieme.

In questo pezzo di codice la cosa più recente che vedi è proprio destructuring assignment che se non sbaglio è arrivato con ES6.
 
  • Mi piace
Reazioni: coronel
Ciao,
onestamente ho guardato la logica che avevi scritto e non mi era chiarissima, inoltre ai fini di quello che chiedevi non era rilevante, quello che ho postato riguarda solo e soltanto la preview di un'immagine caricata.

La "dichiarazione" (assegnazione) che menzioni si chiama Destructuring Assignment, ti lascio la referenza per capire meglio di cosa si tratta.

Per l'input dipende da quello che vuoi fare -- il multiple attribute ti permette di selezionare più file insieme.

In questo pezzo di codice la cosa più recente che vedi è proprio destructuring assignment che se non sbaglio è arrivato con ES6.
capisco, funziona piumeno come un array associativo php, cmq l'idea e quella di xmettere al utente di caricare piu di una foto e di poterle visualizzare in anteprima tutte quante, e il codice che mi hai suggerito ne consente solo la preview di 1 sola, cioe quando vado a caricare la seconda foto prende il posto della prima.. tra l'altro ho fatto una modifica al codice x capire meglio, in questo modo
JavaScript:
var imgInput = document.getElementById('file_input');
imgInput.addEventListener("change", function() {
  img = imgInput.files[0]
  if (img) {
    document.getElementById('preview').src = URL.createObjectURL(img);
  }

e non funziona piu, non capisco come mai
 
Ultima modifica:
Ciao di nuovo,
se vuoi la preview di più immagini devi generare dinamicamente gli elementi nel DOM (a meno che non vuoi seguire un approccio statico ma questo necessita che la quantità di foto caricabili sia ben definita e sempre uguale).
L'approccio dinamico è il seguente:

HTML:
<input type="file" name="file" id="file_input" multiple>
<div id="gallery">
 
</div>

Nota bene: adesso non devi più destrutturare l'array di file in quanto lo stai già traversando con un ciclo!

JavaScript:
const fileInput = document.getElementById('file_input');
fileInput.addEventListener("change", () => {
   for(let file of fileInput.files) {
      const image = file;
      if (image) {
         let imageElement = new Image();
         imageElement.src = URL.createObjectURL(image);
         document.getElementById('gallery').appendChild(imageElement);
      }
   }
});



Vedi: https://jsfiddle.net/DanieleFI/gxq9nkuy/24/


Il codice che hai postato non funziona perché se fa riferimento all'HTML che avevi non hai alcun elemento img con id "preview" a cui settare il source dell'immagine.
 
  • Mi piace
Reazioni: coronel
Ciao di nuovo,
se vuoi la preview di più immagini devi generare dinamicamente gli elementi nel DOM (a meno che non vuoi seguire un approccio statico ma questo necessita che la quantità di foto caricabili sia ben definita e sempre uguale).
L'approccio dinamico è il seguente:

HTML:
<input type="file" name="file" id="file_input" multiple>
<div id="gallery">
 
</div>

Nota bene: adesso non devi più destrutturare l'array di file in quanto lo stai già traversando con un ciclo!

JavaScript:
var fileInput = document.getElementById('file_input');
fileInput.addEventListener("change", () => {
   for(let file of fileInput.files) {
      const image = file;
      if (image) {
         var imageElement = new Image();
         imageElement.src = URL.createObjectURL(image);
         document.getElementById('gallery').appendChild(imageElement);
      }
   }
});



Vedi: https://jsfiddle.net/DanieleFI/gxq9nkuy/21/



Il codice che hai postato non funziona perché se fa riferimento all'HTML che avevi non hai alcun elemento img con id "preview" a cui settare il source dell'immagine.

sbagli. si che ce l lemento img con id preview, te lo riposto di nuovo e ti linko tutto a codepen alla fine
HTML:
<input type="file" name="file" id="file_input" multiple>
<div id="galleria">
    <img id="preview" src="" alt="preview" width=100 />
</div>

JavaScript:
var imgInput = document.getElementById('file_input');
imgInput.addEventListener("change", function() {
  img = imgInput.files[0]
  if (img) {
    document.getElementById('preview').src = URL.createObjectURL(img);
  }
})


Vedi: https://codepen.io/prosteven/pen/oNeQbgM?editors=1010

cmq ho riprovato ora e adesso funziona il mio codice modificato, cmq non ho capito perche dichiari la var image come const ..
 
nb. ho editato la mia risposta, avevo copiato il tuo codice e ho lasciato qualche typo.

Ho fatto riferimento all'HTML che hai postato nel primo messaggio della discussione, che non aveva alcun tag image con id preview, e l'unica spiegazione per il quale potesse darti errore era che non avessi quell'elemento (ndr., non hai postato HTML nella domanda prima della mia risposta), ergo la mia risposta :D

https://www.freecodecamp.org/news/var-let-and-const-whats-the-difference/ per capire perché usare const e let invece di var.

p.s. ovviamente per far funzionare la preview multipla devi generarti gli elementi della galleria dinamicamente, traversando l'array di FileInput.
 
  • Mi piace
Reazioni: coronel
nb. ho editato la mia risposta, avevo copiato il tuo codice e ho lasciato qualche typo.

Ho fatto riferimento all'HTML che hai postato nel primo messaggio della discussione, che non aveva alcun tag image con id preview, e l'unica spiegazione per il quale potesse darti errore era che non avessi quell'elemento (ndr., non hai postato HTML nella domanda prima della mia risposta), ergo la mia risposta :D

https://www.freecodecamp.org/news/var-let-and-const-whats-the-difference/ per capire perché usare const e let invece di var.

p.s. ovviamente per far funzionare la preview multipla devi generarti gli elementi della galleria dinamicamente, traversando l'array di FileInput.
ho fatto alcune modifiche e ha funzionato, ti lascio il risultato1

Vedi: https://codepen.io/prosteven/pen/oNeQbgM
cmq ora vorrei avere la possibilita tramite un button di rimuovere le foto che voglio che avevo caricato, .. come potrei fare secondo te? visto che e tutto generato in modo dinamico risulta piu complicato
 
Da quanto so FileList è readonly e non c'è modo di modificarne il contenuto.
Per modificare (ndr. rimuovere elementi) dall'input hai necessità di customizzare la gestione delle immagini stesse.
E' un po' tedioso e richiede un po' di tempo, puoi provare a fare qualche ricerca e trovare una soluzione che ti si addice (ricerca).
Rimuovere le preview dal DOM invece è semplice, però non penso ti sia utile visto che comunque rimarrebbero nella coda dell'input.
 
Da quanto so FileList è readonly e non c'è modo di modificarne il contenuto.
Per modificare (ndr. rimuovere elementi) dall'input hai necessità di customizzare la gestione delle immagini stesse.
E' un po' tedioso e richiede un po' di tempo, puoi provare a fare qualche ricerca e trovare una soluzione che ti si addice (ricerca).
Rimuovere le preview dal DOM invece è semplice, però non penso ti sia utile visto che comunque rimarrebbero nella coda dell'input.
In che senso nella coda del input scusa? Io voglio qualcosa tipo kijiji se hai presente che quando vai a mettere in vendita qualcosa nella sezione di foto ti fa aggiungere foto e rimioverle
 
Nel senso che i file presenti nella FileList, che è l'oggetto che viene usato dalle input (type="file"), non è modificabile.
Quindi, nel momento in cui tu aggiungi dei file, non hai modo di cambiarne solo alcuni - infatti se provi a caricare dei nuovi file quelli precedenti verranno sovrascritti.
Ciò non toglie che puoi provare a crearti il tuo oggetto con il quale gestirti le immagini caricate e renderlo accessibile, oppure puoi appoggiarti a soluzioni alternative già postate - che ignoro - ma sulle quali puoi fare un po' di ricerca!
Sono abbastanza sicuro che gli sviluppatori di Kijiji abbiano customizzato i loro input delle immagini affinché l'utente potesse avere pieno controllo su di esse :)
 
Nel senso che i file presenti nella FileList, che è l'oggetto che viene usato dalle input (type="file"), non è modificabile.
Quindi, nel momento in cui tu aggiungi dei file, non hai modo di cambiarne solo alcuni - infatti se provi a caricare dei nuovi file quelli precedenti verranno sovrascritti.
Ciò non toglie che puoi provare a crearti il tuo oggetto con il quale gestirti le immagini caricate e renderlo accessibile, oppure puoi appoggiarti a soluzioni alternative già postate - che ignoro - ma sulle quali puoi fare un po' di ricerca!
Sono abbastanza sicuro che gli sviluppatori di Kijiji abbiano customizzato i loro input delle immagini affinché l'utente potesse avere pieno controllo su di esse :)
..cmq guarda io l.ho altro giorno ho usato il metodo files del input file e questo metodo è una specie di array , quindi io riesco ad accedere a tutte le foto che avevo caricato su questo input file, poi non saprei, dovrei riprovare x rivedere
 
Sono abbastanza sicuro che l'oggetto che viene utilizzato sia comunque una FileList.
Comunque se fosse un array normale la gestione sarebbe abbastanza semplice :)
 
  • Mi piace
Reazioni: Sunacchi
Ciao, mi dispiace ma anche se volessi non ne avrei fisicamente il tempo!
Posso però continuare a darti delle dritte qui su inforge come per il discorso delle preview, la cosa che comunque (vi) ti consiglio è provare, provare e riprovare, sbattere la testa su queste cose e soprattutto fare ricerca riguardo tutto ciò che non ti è chiaro e cercare di imparare le cose che (per ora) non sai! :)
 
  • Mi piace
Reazioni: coronel
Ciao, mi dispiace ma anche se volessi non ne avrei fisicamente il tempo!
Posso però continuare a darti delle dritte qui su inforge come per il discorso delle preview, la cosa che comunque (vi) ti consiglio è provare, provare e riprovare, sbattere la testa su queste cose e soprattutto fare ricerca riguardo tutto ciò che non ti è chiaro e cercare di imparare le cose che (per ora) non sai! :)
scusa sapresti dirmi come mai il listener che ho assegnato a tutte le img non va?

Vedi: https://codepen.io/prosteven/pen/oNeQbgM
 
Ciao,
ti consiglio di pulire un po' il codice perché è difficile da leggere ed interpretare al volo :)

Comunque, a quale event listener ti stai riferendo?

JavaScript:
$("img").click(function() {
    console.log(4);
})

Questo?

P.S. Ti chiedo inoltre di usare JSFiddle, è più comodo visto che stai usando jQuery, perché permette l'import diretto della libreria!
 
  • Mi piace
Reazioni: coronel
Ciao,
ti consiglio di pulire un po' il codice perché è difficile da leggere ed interpretare al volo :)

Comunque, a quale event listener ti stai riferendo?

JavaScript:
$("img").click(function() {
    console.log(4);
})

Questo?

P.S. Ti chiedo inoltre di usare JSFiddle, è più comodo visto che stai usando jQuery, perché permette l'import diretto della libreria!
Si mi riferivo a quel listener, e vabene userp jsfiddle
 
Ho provato il tuo codice e quel listener funziona, quando viene fatto un click sull'imagine viene loggato "4".
Sicuro che non ti stia funzionando?
 
  • Mi piace
Reazioni: coronel
Ultima modifica:
Danyyy brooo, nn mi abbandonare ^_^, hai visto che non va il mio codice? Cmq riguarda a js fiddle e codepen, sappi che anche su codepen si può importare la libreria di jqiery
Stai usando la versione corretta di JQuery?
Se usi vanilla js (ndr. addEventListener) ti funziona?
Non credo che il problema sia dovuto alla versione di jquery visto che senza quei menuselect funziona il listener dei IMG... Proverò a farlo con vjs ma nn credo cambi il risultato
Messaggio unito automaticamente:

guarda, stesso risultato con vjs

Vedi: https://codepen.io/prosteven/pen/mdMvMYg?editors=1011

Messaggio unito automaticamente:

Dani scusa il disturbo, 6 riuscito a identificare il problema? Io x piu ch3 ci provo.nn riesco
Messaggio unito automaticamente:

@Dany© fammi sapere x favore
Messaggio unito automaticamente:

sn riuscito a risolvere il problema col listener delle img, ora ho un altro problema sempre col listener di imageelement2 e questa volta mi segnala errore di syntax ma e tutto scritto bene, dagli un occhiata xfav

Vedi: https://codepen.io/prosteven/pen/mdMvMYg?editors=0010
 
Ciao,
come ti ho anticipato non ho fisicamente il tempo per seguire il progetto, posso risponderti quando ho un attimo libero :)

Il problema è qui:
JavaScript:
imageElement2.css("transform":"rotate(-90)");
Ti consiglio di leggere le docs della funzione css() di jQuery per capire meglio come funziona.

La soluzione (tenendo per filo e per segno ciò che stai cercando di fare tu) è questa:
JavaScript:
$(imageElement2).on('click', function() {
    $(imageElement2).css({ WebkitTransform: 'rotate(-90deg)'});
});

Comunque, ci sono diversi problemi e ti invito (consiglio) a rifletterci:
  • Il codice è confuso e alla lunga ti renderai conto che non è mantenibile - è fondamentale, per il proseguo del progetto, che tu riesca a pulirlo e cercare di seguire uno standard (ndr. il prossimo punto parla di questo);
  • Stai facendo un po' di confusione nell'utilizzo di jQuery (ti consiglio di guardare attentamente le docs per capire in principio come si usa jQuery e fare più attenzione all'utilizzo delle sue funzioni) e VanillaJS - ricordati che non puoi utilizzare jQuery su elementi VJS (o almeno, non direttamente), questo era un altro problema nel codice - è giusto usare jQuery over Vanilla ove serve, però se decidi di standardizzare il progetto con l'utilizzo di jQuery devi anche mantenerne la logica.
Ti chiedo nuovamente di usare JSFiddle, è molto, molto, molto più facile consultare il codice e debuggarlo per chi ti aiuta :D
 
  • Mi piace
Reazioni: coronel
Ciao,
come ti ho anticipato non ho fisicamente il tempo per seguire il progetto, posso risponderti quando ho un attimo libero :)

Il problema è qui:
JavaScript:
imageElement2.css("transform":"rotate(-90)");
Ti consiglio di leggere le docs della funzione css() di jQuery per capire meglio come funziona.

La soluzione (tenendo per filo e per segno ciò che stai cercando di fare tu) è questa:
JavaScript:
$(imageElement2).on('click', function() {
    $(imageElement2).css({ WebkitTransform: 'rotate(-90deg)'});
});

Comunque, ci sono diversi problemi e ti invito (consiglio) a rifletterci:
  • Il codice è confuso e alla lunga ti renderai conto che non è mantenibile - è fondamentale, per il proseguo del progetto, che tu riesca a pulirlo e cercare di seguire uno standard (ndr. il prossimo punto parla di questo);
  • Stai facendo un po' di confusione nell'utilizzo di jQuery (ti consiglio di guardare attentamente le docs per capire in principio come si usa jQuery e fare più attenzione all'utilizzo delle sue funzioni) e VanillaJS - ricordati che non puoi utilizzare jQuery su elementi VJS (o almeno, non direttamente), questo era un altro problema nel codice - è giusto usare jQuery over Vanilla ove serve, però se decidi di standardizzare il progetto con l'utilizzo di jQuery devi anche mantenerne la logica.
Ti chiedo nuovamente di usare JSFiddle, è molto, molto, molto più facile consultare il codice e debuggarlo per chi ti aiuta :D
io uso firefox, cmq nn va neanche su jsfiddle, la foto non si gira


Vedi: https://jsfiddle.net/soyrhc8p/
 
Stato
Discussione chiusa ad ulteriori risposte.