Acara pemilihan file input HTML tidak diaktifkan setelah memilih file yang sama

204

Apakah ada peluang untuk mendeteksi setiap pemilihan file yang dibuat pengguna untuk elemen inputtipe HTML file?

Ini telah ditanyakan berkali-kali sebelumnya, tetapi acara yang biasanya diusulkan onchangetidak menyala jika pengguna memilih file yang sama lagi.

dronus
sumber
7
Apakah kode Anda kemudian juga harus diaktifkan jika pengguna menekan Batalkan? Seseorang berharap bahwa menekan Cancel tidak akan melakukan apa-apa, dan saya pikir sebagian besar pengguna lebih lanjut berharap bahwa memilih kembali file yang sama akan memiliki efek yang sama dengan Cancel. Saya tidak tahu apakah ini mungkin atau tidak, tetapi saya sarankan Anda mempertimbangkan kembali desain ini.
KRyan
1
Pada pembatalan itu seharusnya tidak menyala atau membuatnya terdeteksi. Ini lebih dimaksudkan untuk menghapus UI ceveat: Jika beberapa tindakan dipanggil setelah file dipilih, pengguna biasanya mengharapkan tindakan untuk mengulangi jika ia memilih file lagi.
dronus
Mungkin kita dapat memiliki perilaku ini jika kita menetapkan inputnilai ke '' setelah melakukan sesuatu dengan file tersebut. Tapi itu juga akan menghapus nama file yang terlihat. Namun, itu mungkin ok, karena file tersebut benar-benar diproses dan hasil dari tindakan itu dapat muncul di tempat lain.
dronus
Tolong Jelaskan tentang Que. Apa yang ingin Anda lakukan?
Juara
1
Yang saya inginkan adalah mensimulasikan aplikasi desktop perilaku sekolah lama miliki. Jika saya 'membuka' file yang sama lagi di aplikasi desktop, itu biasanya dimuat ulang, atau jika beberapa tindakan dilakukan dengan file (seperti mengonversinya jadi format lain misalnya) tindakan ini dilakukan lagi. Inilah yang mungkin diharapkan pengguna desktop dari aplikasi web, tetapi acara fileinput onchangetidak mirip.
dronus

Jawaban:

279

Tetapkan nilai inputto nullpada setiap onclickacara. Ini akan mengatur ulang inputnilai dan memicu onchangeacara bahkan jika jalur yang sama dipilih.

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

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

Ini DEMO .

Catatan: Adalah normal jika file Anda diawali dengan 'C: \ fakepath \'. Itu fitur keamanan yang mencegah JavaScript untuk mengetahui jalur absolut file. Browser masih mengetahuinya secara internal.

Brian Ustas
sumber
1
Saya mencoba demo, tetapi (menggunakan Chrome 21) saya terus mendapatkan `C: \ fakepath` + lalu nama file yang saya pilih (tidak termasuk path). Peringatan ini ditampilkan pada setiap pilih file yang sama.
Jasper de Vries
1
@JasperdeVries Itu adalah fitur keamanan yang mencegah JavaScript untuk mengetahui jalur absolut file. Browser masih mengetahui jalur secara internal.
Brian Ustas
1
Selain itu, null adalah satu-satunya nilai yang diizinkan untuk <input type = "file">. Jadi jika Anda mencoba mengaturnya menjadi tidak terdefinisi dan mendapatkan pengecualian maka itulah alasannya.
Noel Abrahams
5
Itu tidak bekerja dengan baik di IE11 kecuali Anda membuat perubahan kecil: demo .
21
Lebih baik meletakkannya this.value = nulldi akhir onchangekarena dimungkinkan untuk mengaktifkan elemen input tanpa mengkliknya (dengan menggunakan keyboard). Anda dapat menyimpan input.filesjika perlu referensi nanti.
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; hanya diperlukan untuk Chrome, Firefox akan berfungsi dengan baik hanya dengan return false;

Ini FIDDLE

elshnkhll
sumber
2
sederhana dan efektif hanya diuji di IE dan chrome terbaru dan bekerja seperti pesona. Terima kasih telah membagikannya
Atul Chaudhary
8

Dalam artikel ini, di bawah judul "Menggunakan input formulir untuk memilih"

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>

Itu menambahkan pendengar acara ke 'perubahan', tapi saya mengujinya dan memicu bahkan jika Anda memilih file yang sama dan tidak jika Anda membatalkan.

Xacur Aphrantus
sumber
Mempertimbangkan kemungkinan makna ambigu dari "perubahan" dalam kasus ini, apakah Anda mencoba ini di banyak browser? Anda mungkin ingin menentukan yang mana Anda mencobanya seperti di web, browser tidak selalu dalam konsensus tentang hal-hal ini.
Thor84no
2
Lingkungan apa yang Anda gunakan untuk pengujian Anda? Pengalaman saya dengan Chrome adalah yang saya nyatakan dalam pertanyaan, changeacara hanya akan memunculkan perubahan nama file.
dronus
7

Gunakan acara onClick untuk menghapus nilai input target, setiap kali pengguna mengklik bidang. Ini memastikan bahwa acara onChange akan dipicu untuk file yang sama juga. Bekerja untuk saya :)

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

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

Menggunakan TypeScript

onInputClick = ( event: React.MouseEvent<HTMLInputElement, MouseEvent>) => {
    const element = event.target as HTMLInputElement
    element.value = ''
}
Hukum Trafalgar
sumber
Terima kasih atas solusinya.
Deepak Tekchandani
1

Lakukan apa pun yang ingin Anda lakukan setelah file berhasil dimuat. Tepat setelah penyelesaian pemrosesan file Anda, atur nilai kontrol file ke string kosong. Jadi .change () akan selalu dipanggil meskipun nama file berubah atau tidak. seperti misalnya Anda dapat melakukan hal ini dan bekerja untuk saya seperti pesona

   $('#myFile').change(function () {
       LoadFile("myFile");//function to do processing of file.
       $('#myFile').val('');// set the value to empty of myfile control.
    });
Mohit Singh
sumber
1
handleChange({target}) {
    const files = target.files
    target.value = ''
}
Shashwat Gupta
sumber
1
Hey ngCourse! Jawaban hanya kode dapat memecahkan masalah tetapi mereka jauh lebih berguna jika Anda menjelaskan bagaimana mereka menyelesaikannya. Komunitas membutuhkan teori dan kode untuk memahami jawaban Anda sepenuhnya.
RBT
Sementara kode ini dapat menyelesaikan pertanyaan, termasuk penjelasan tentang bagaimana dan mengapa ini menyelesaikan masalah akan sangat membantu untuk meningkatkan kualitas posting Anda, dan mungkin menghasilkan lebih banyak suara. Ingatlah bahwa Anda menjawab pertanyaan untuk pembaca di masa depan, bukan hanya orang yang bertanya sekarang. Harap edit jawaban Anda untuk menambahkan penjelasan dan berikan indikasi tentang batasan dan asumsi apa yang berlaku. Dari Ulasan
double-beep
1

Menghapus nilai indeks input 0 bekerja untuk saya . Silakan coba kode di bawah ini, semoga ini berhasil (AngularJs).

          scope.onClick = function() {
            input[0].value = "";
                input.click();
            };
Dilip Kumar
sumber