Auswahlereignis für HTML-Eingabedateien wird bei Auswahl derselben Datei nicht ausgelöst


204

Gibt es eine Möglichkeit, jede Dateiauswahl zu erkennen, die der Benutzer für ein HTML- Element inputvom Typ getroffen hat file?

Dies wurde schon oft gefragt, aber das normalerweise vorgeschlagene onchangeEreignis wird nicht ausgelöst, wenn der Benutzer dieselbe Datei erneut auswählt.


7
Müsste Ihr Code dann auch ausgelöst werden, wenn der Benutzer dann auf Abbrechen klickt? Man geht davon aus, dass das Drücken von Abbrechen nichts bringt, und ich denke, die meisten Benutzer würden weiterhin erwarten, dass die erneute Auswahl derselben Datei den gleichen Effekt hat wie das Abbrechen. Ich weiß nicht, ob dies möglich ist oder nicht, aber ich schlage vor, dass Sie dieses Design trotzdem überdenken.
KRyan

1
Beim Abbrechen sollte es nicht ausgelöst oder anderweitig erkennbar gemacht werden. Es ist eher dazu gedacht, einen UI-Ceveat zu entfernen: Wenn eine Aktion aufgerufen wird, nachdem die Datei ausgewählt wurde, erwartet der Benutzer normalerweise, dass die Aktion wiederholt wird, wenn er die Datei erneut auswählt.
Dronus

Vielleicht können wir dieses Verhalten haben, wenn wir den inputWert s auf '' setzen, nachdem wir etwas mit der Datei gemacht haben. Aber das würde auch den sichtbaren Dateinamen entfernen. Dies kann jedoch in Ordnung sein, da die Datei tatsächlich verarbeitet wird und das Ergebnis dieser Aktion möglicherweise an einer anderen Stelle angezeigt wird.
Dronus

Bitte erläutern Sie die Warteschlange Was möchten Sie tun?
Champ

1
Ich möchte nur das Verhalten von Desktop-Anwendungen der alten Schule simulieren. Wenn ich dieselbe Datei in einer Desktop-Anwendung erneut "öffne", wird sie normalerweise neu geladen, oder wenn eine Aktion mit der Datei ausgeführt wird (z. B. das Konvertieren in ein anderes Format), wird diese Aktion erneut ausgeführt. Dies können Desktop-Benutzer auch von einer Web-App erwarten, aber das fileEingabeereignis onchangeähnelt nicht.
Dronus

Antworten:


278

Setzen Sie den Wert der inputzu nullauf jeder onclickVeranstaltung. Dadurch wird der inputWert des 's zurückgesetzt und das onchangeEreignis ausgelöst , auch wenn derselbe Pfad ausgewählt ist.

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

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

Hier ist eine DEMO .

Hinweis: Es ist normal, wenn Ihrer Datei das Präfix "C: \ fakepath \" vorangestellt ist. Dies ist eine Sicherheitsfunktion, die verhindert, dass JavaScript den absoluten Pfad der Datei kennt. Der Browser weiß es noch intern.


1
Ich habe die Demo ausprobiert, aber (mit Chrome 21) erhalte ich immer wieder "C: \ fakepath" + und dann den von mir ausgewählten Dateinamen (ohne den Pfad). Die Warnung wird jedoch bei jeder Auswahl derselben Datei angezeigt.
Jasper de Vries

1
@JasperdeVries Dies ist eine Sicherheitsfunktion, die verhindert, dass JavaScript den absoluten Pfad einer Datei kennt. Der Browser kennt den Pfad weiterhin intern.
Brian Ustas

1
Abgesehen davon ist null der einzige zulässige Wert für <input type = "file">. Wenn Sie also versuchen, es auf undefiniert zu setzen und eine Ausnahme zu erhalten, ist dies der Grund dafür.
Noel Abrahams

5
In IE11 funktioniert es nur, wenn Sie eine kleine Änderung vornehmen: Demo .

21
Es ist besser, this.value = nullam Ende von zu setzen, onchangeda es möglich ist, ein Eingabeelement zu aktivieren, ohne darauf zu klicken (über die Tastatur). Sie können speichern, input.fileswenn Sie später darauf verweisen müssen.
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; ist nur für Chrome erforderlich, Firefox funktioniert nur mit return false;

Hier ist ein FIDDLE


2
Einfach und effektiv, gerade in neuestem IE und Chrom getestet und funktioniert wie ein Zauber. Vielen Dank für das Teilen
Atul Chaudhary

8

In diesem Artikel unter dem Titel "Verwenden der Formulareingabe zur Auswahl"

http://www.html5rocks.com/de/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>

Es fügt einen Ereignis-Listener zu 'change' hinzu, aber ich habe ihn getestet und er wird ausgelöst, selbst wenn Sie dieselbe Datei auswählen und nicht, wenn Sie abbrechen.


Haben Sie dies angesichts der möglicherweise mehrdeutigen Bedeutung von "Änderung" in diesem Fall in mehreren Browsern versucht? Möglicherweise möchten Sie angeben, welche Sie wie im Web anprobiert haben. Browser sind sich in diesen Punkten nicht immer einig.
Thor84no

2
Welche Umgebung verwenden Sie für Ihren Test? Meine Erfahrung mit Chrome war die, die ich in der Frage angegeben habe. Das changeEreignis wird nur bei Dateinamenänderungen ausgelöst.
Dronus

7

Verwenden Sie das Ereignis onClick, um den Wert der Zieleingabe jedes Mal zu löschen, wenn der Benutzer auf das Feld klickt. Dadurch wird sichergestellt, dass das Ereignis onChange auch für dieselbe Datei ausgelöst wird. Arbeitete für mich :)

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

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

Verwenden von TypeScript

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

Danke für die Lösung.
Deepak Tekchandani

1

Tun Sie, was immer Sie tun möchten, nachdem die Datei erfolgreich geladen wurde. Setzen Sie den Wert der Dateisteuerung nach Abschluss Ihrer Dateiverarbeitung auf eine leere Zeichenfolge. Daher wird .change () immer aufgerufen, auch wenn sich der Dateiname ändert oder nicht. wie zum Beispiel kannst du dieses Ding machen und hast für mich wie Charme gearbeitet

   $('#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
Hey ngCourse! Nur-Code-Antworten können das Problem lösen, aber sie sind viel nützlicher, wenn Sie erklären, wie sie es lösen. Community erfordert sowohl Theorie als auch Code, um Ihre Antwort vollständig zu verstehen.
RBT

Während dieser Code die Frage lösen kann, einschließlich einer Erklärung, wie und warum dies das Problem löst, würde dies wirklich dazu beitragen, die Qualität Ihres Beitrags zu verbessern, und wahrscheinlich zu mehr Up-Votes führen. Denken Sie daran, dass Sie in Zukunft die Frage für die Leser beantworten, nicht nur für die Person, die jetzt fragt. Bitte bearbeiten Sie Ihre Antwort, um Erklärungen hinzuzufügen und anzugeben, welche Einschränkungen und Annahmen gelten. Aus der Überprüfung
Doppel-Piepton

1

Das Löschen des Werts des 0. Index der Eingabe hat bei mir funktioniert . Bitte versuchen Sie den folgenden Code, hoffen Sie, dass dies funktioniert (AngularJs).

          scope.onClick = function() {
            input[0].value = "";
                input.click();
            };
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.