Evento di selezione del file di input HTML non attivato quando si seleziona lo stesso file


204

C'è qualche possibilità di rilevare ogni selezione di file effettuata dall'utente per un HTML inputdi tipo fileelemento?

Questo è stato chiesto molte volte prima, ma l' onchangeevento solitamente proposto non si attiva se l'utente seleziona nuovamente lo stesso file.


7
Il tuo codice dovrebbe quindi essere attivato anche se l'utente preme Annulla? Ci si aspetta che premere Annulla non farà nulla, e penso che la maggior parte degli utenti si aspetterebbe che la nuova selezione dello stesso file avrebbe lo stesso effetto di Annulla. Non so se questo sia possibile o no, ma ti suggerisco di riconsiderare questo progetto comunque.
KRyan,

1
All'annullamento non dovrebbe sparare o renderlo altrimenti rilevabile. È più pensato per rimuovere un ceveat dell'interfaccia utente: se viene invocata qualche azione dopo la scelta del file, l'utente si aspetta solitamente che l'azione si ripeta se sceglie di nuovo il file.
dronus,

Forse possiamo avere questo comportamento se impostiamo il inputvalore s su '' dopo aver fatto qualcosa con il file. Ma questo eliminerebbe anche il nome file visibile. Tuttavia, ciò potrebbe essere ok, poiché il file viene effettivamente elaborato e il risultato di tale azione potrebbe apparire da qualche altra parte.
dronus,

Plz Spiega il Que Cosa vuoi fare?
Champ

1
Tutto quello che voglio è simulare il comportamento delle applicazioni desktop della vecchia scuola. Se 'apro' di nuovo lo stesso file in un'applicazione desktop, di solito viene ricaricato, o se viene eseguita qualche azione con il file (come la conversione in un altro formato, ad esempio), questa azione viene ripetuta. Questo è ciò che gli utenti desktop possono aspettarsi anche da un'app Web, ma l' evento di fileinput onchangenon assomiglia.
dronus,

Risposte:


279

Impostare il valore di inputsu nullsu ciascun onclickevento. Ciò ripristinerà il inputvalore e attiverà l' onchangeevento anche se è selezionato lo stesso percorso.

input.onclick = function () {
    this.value = null;
};

input.onchange = function () {
    alert(this.value);
};​

Ecco una DEMO .

Nota: è normale se il tuo file ha il prefisso 'C: \ fakepath \'. Questa è una funzione di sicurezza che impedisce a JavaScript di conoscere il percorso assoluto del file. Il browser lo sa ancora internamente.


1
Ho provato la demo, ma (usando Chrome 21) continuo a ottenere `C: \ fakepath` + quindi il nome file che ho selezionato (escluso il percorso). Tuttavia, l'avviso viene mostrato su ogni selezione dello stesso file.
Jasper de Vries,

1
@JasperdeVries Questa è una funzione di sicurezza che impedisce a JavaScript di conoscere il percorso assoluto di un file. Il browser conosce ancora il percorso internamente.
Brian Ustas,

1
A parte questo, null è l'unico valore consentito per <input type = "file">. Quindi, se stai cercando di impostarlo su indefinito e ottenere un'eccezione, questo è il motivo.
Noel Abrahams,

5
Non funziona bene in IE11 a meno che non apporti una piccola modifica: demo .

21
È meglio metterlo this.value = nullalla fine del onchangeperché è possibile attivare un elemento di input senza fare clic su di esso (utilizzando la tastiera). È possibile memorizzare input.filesse è necessario fare riferimento in un secondo momento.
Halcyon,

24
<form enctype='multipart/form-data'>
    <input onchange="alert(this.value); this.value=null; return false;" type='file'>
    <br>
    <input type='submit' value='Upload'>
</form>

this.value=null; è necessario solo per Chrome, Firefox funzionerà bene solo con return false;

Ecco un FIDDLE


2
semplice ed efficace appena testato negli ultimi IE e Chrome e funziona come un fascino. Grazie per averlo condiviso
Atul Chaudhary,

8

In questo articolo, sotto il titolo "Utilizzo dell'input del modulo per la selezione"

http://www.html5rocks.com/en/tutorials/file/dndfiles/

<input type="file" id="files" name="files[]" multiple />

<script>
function handleFileSelect(evt) {

    var files = evt.target.files; // FileList object

    // files is a FileList of File objects. List some properties.
    var output = [];
    for (var i = 0, f; f = files[i]; i++) {
     // Code to execute for every file selected
    }
    // Code to execute after that

}

document.getElementById('files').addEventListener('change', 
                                                  handleFileSelect, 
                                                  false);
</script>

Aggiunge un listener di eventi a "modifica", ma l'ho provato e si innesca anche se si sceglie lo stesso file e non se si annulla.


Considerando il significato potenzialmente ambiguo di "cambiamento" in questo caso, l'hai provato in più browser? Potresti voler specificare quelli su cui l'hai provato come sul web, i browser non sono sempre sempre d'accordo su queste cose.
Thor84no,

2
Quale ambiente usi per il tuo test? La mia esperienza con Chrome è stata quella che ho affermato nella domanda, l' changeevento si attiva solo con le modifiche al nome del file.
dronus,

7

Utilizzare l'evento onClick per cancellare il valore dell'input target, ogni volta che l'utente fa clic sul campo. Ciò garantisce che l'evento onChange verrà attivato anche per lo stesso file. Ha funzionato per me :)

onInputClick = (event) => {
    event.target.value = ''
}

<input type="file" onChange={onFileChanged} onClick={onInputClick} />

Utilizzando TypeScript

onInputClick = ( event: React.MouseEvent<HTMLInputElement, MouseEvent>) => {
    const element = event.target as HTMLInputElement
    element.value = ''
}

Grazie per la soluzione
Deepak Tekchandani il

1

Fai quello che vuoi fare dopo che il file è stato caricato correttamente. Solo dopo il completamento dell'elaborazione del file, imposta il valore del controllo del file su stringa vuota. Quindi .change () verrà sempre chiamato anche se il nome del file cambia o meno. come ad esempio puoi fare questa cosa e lavorare per me come per incanto

   $('#myFile').change(function () {
       LoadFile("myFile");//function to do processing of file.
       $('#myFile').val('');// set the value to empty of myfile control.
    });

1
handleChange({target}) {
    const files = target.files
    target.value = ''
}

1
Ehi, tesoro! Le risposte di solo codice possono risolvere il problema, ma sono molto più utili se spieghi come risolverlo. La community richiede sia la teoria che il codice per comprendere appieno la tua risposta.
RBT

Sebbene questo codice possa risolvere la domanda, inclusa una spiegazione di come e perché questo risolva il problema, aiuterebbe davvero a migliorare la qualità del tuo post e probabilmente si tradurrà in più voti positivi. Ricorda che stai rispondendo alla domanda per i lettori in futuro, non solo per la persona che chiede ora. Si prega di modificare la risposta per aggiungere spiegazioni e dare un'indicazione di ciò si applicano le limitazioni e le assunzioni. Dalla recensione
Doppio segnale acustico

1

Cancellare il valore del 0 ° indice di input ha funzionato per me . Prova il codice seguente, spero che funzioni (AngularJs).

          scope.onClick = function() {
            input[0].value = "";
                input.click();
            };
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.