Memicu kotak dialog "pilih file" secara terprogram

100

Saya memiliki elemen input file tersembunyi. Apakah mungkin untuk memicu kotak dialog pilih file dari acara klik tombol?

tamakisquare
sumber

Jawaban:

146

Jika Anda ingin memiliki tombol sendiri untuk mengupload file daripada menggunakan <input type="file" />, Anda dapat melakukan sesuatu seperti:

<input id="myInput" type="file" style="visibility:hidden" />
<input type="button" value="Show Dialog" onclick="$('#myInput').click();" />

Perhatikan bahwa saya menggunakan visibility: hidden, bukan display: none. Anda tidak dapat memanggil peristiwa klik pada input file yang tidak ditampilkan.

Mike Gwilt
sumber
Langsung untuk kasus dasar, tetapi tidak kompatibel dengan banyak browser. Harap dicatat bahwa ide yang jauh lebih baik untuk menggabungkan solusi ini dengan melapisi elemen input file di atas tombol pada opacity: 0, seperti yang telah disebutkan dalam jawaban Xeon06.
SquareCat
10
Pembaruan: Di browser modern Anda dapat mengklik input yang bahkan tidak ada di DOM. Hebat!
Adria
7
saya hanya mencoba click()pada display:nonemasukan dan bekerja
Daniel Cheung
15
Ya, di sini di tahun 2015 ini, click()ada elemen dengan display: nonekarya! ;) Bagaimana hal-hal berubah dalam empat tahun terakhir.
ffxsam
Anda dapat menggunakan hiddenatribut sebagai gantinya style="visibility:hidden": <input id="myInput" type="file" hidden>( w3schools.com/tags/att_global_hidden.asp )
cespon
114

Sebagian besar jawaban di sini kurang memiliki informasi yang berguna:

Ya, Anda dapat mengklik secara terprogram elemen input menggunakan jQuery / JavaScript, tetapi hanya jika Anda melakukannya di event handler milik event YANG DIMULAI OLEH PENGGUNA!

Jadi, misalnya, tidak akan terjadi apa-apa jika Anda, skrip, secara terprogram mengklik tombol di callback ajax, tetapi jika Anda meletakkan baris kode yang sama di penangan peristiwa yang dimunculkan oleh pengguna, itu akan berfungsi.

PS Kata debugger;kunci mengganggu jendela jelajah jika sebelum klik program ... setidaknya di chrome 33 ...

Fazi
sumber
sebagaimana @LouisBataillard berhak menyebutkan: tidak hanya event handler asli harus dimulai oleh pengguna; itu harus secara khusus merupakan peristiwa klik. Ini biola yang dia sediakan untuk mendemonstrasikan ini: tautan
Souhaieb Besbes
1
Anda dapat mengklik sesuatu yang dibuat secara dinamis. dalam jquery, yaitu$(staticElementParent).on("click", "dynamicChild", function(){})
Daniel Cheung
1
TERIMA KASIH!!!! Saya telah menguji semua jawaban ini di konsol javascript dan saya sudah gila!
jdkealy
8
Saya telah berjuang selama setengah jam dengan jendela input file secara terprogram. TIDAK ADA ORANG LAIN yang menyatakan bahwa tidak mungkin jika acara tidak dimulai oleh pengguna ... Anda berhak mendapatkan banyak +1.
Umagon
1
Mulai Chrome 62, debugger;kata kunci tidak lagi mengganggu klik terprogram
Chris W.
62

Sekadar catatan, ada solusi alternatif yang tidak membutuhkan javascript. Ini sedikit hack, mengeksploitasi fakta bahwa mengklik label menetapkan fokus pada input terkait.

Anda membutuhkan <label>dengan foratribut yang tepat (menunjuk ke input), dengan gaya optionnaly seperti tombol (dengan bootstrap, gunakan btn btn-default). Saat pengguna mengklik label, dialog terbuka, contoh:

<!-- optionnal, to add a bit of style -->
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet"/>

<!-- minimal setup -->
<label for="exampleInput" class="btn btn-default">
  Click me
</label>
<input type="file" id="exampleInput" style="display: none" />

m_x
sumber
2
Saya suka yang ini, tidak ingin menyertakan jQuery penuh dalam proyek Angular saya, berfungsi dengan baik :)
Starscream1984
1
apakah perilaku ini dapat diandalkan di semua browser modern?
JoshuaDavid
Ini berfungsi tanpa JS apa pun, menggunakan perilaku browser asli. Dipasangkan dengan acara onDrop, mengimplementasikan upload file kaya fitur bekerja dengan baik!
Yanick Rochon
Saya harus mengutak-atik CSS tetapi kemudian berhasil - yaitu visibilitas input file yang memiliki "display: none" tidak baik di semua browser. (Tapi opacity 0, dll, dapat digunakan)
driftcatcher
13

Saya tidak yakin bagaimana browser menangani klik pada type="file"elemen (masalah keamanan dan semuanya), tetapi ini seharusnya berfungsi:

$('input[type="file"]').click();

Saya telah menguji JSFiddle ini di Chrome, Firefox dan Opera dan semuanya menampilkan dialog jelajah file.

Bojangles
sumber
5
Tampaknya ini hanya berfungsi jika peristiwa "memanggil" itu sendiri adalah peristiwa klik. Misalnya, sepertinya tidak mungkin untuk membuka dialog file berdasarkan hoverperistiwa: jsfiddle.net/UQfaZ/1
Louis B.
Tahukah Anda bagaimana ini dapat diuji dengan Selenium jika input tidak ada di DOM?
Sebastien Lorber
4

Saya membungkusnya dengan input[type=file]label tag, lalu mengatur gaya labelsesuai keinginan Anda, dan menyembunyikan input.

<label class="btn btn-default fileLabel" data-toggle="tooltip" data-placement="top" title="Upload">
    <input type="file">
    <span><i class="fa fa-upload"></i></span>
</label>

<style>
    .fileLabel input[type="file"] {
        position: fixed;
        top: -1000px;
    }
</style>

Solusi CSS Murni.

Ponyboy
sumber
Cukup setel <input type="file" hidden>untuk menghilangkan kebutuhan untuk menerapkan gaya CSS.
Sylvain Lesage
3

Secara native, satu-satunya cara adalah dengan membuat <input type="file">elemen dan kemudian mensimulasikan klik, sayangnya.

Ada plugin kecil (steker tidak tahu malu) yang akan menghilangkan rasa sakit karena harus melakukan ini sepanjang waktu: file-dialog

fileDialog()
    .then(file => {
        const data = new FormData()
        data.append('file', file[0])
        data.append('imageName', 'flower')

        // Post to server
        fetch('/uploadImage', {
            method: 'POST',
            body: data
        })
    })
Alister
sumber
3

Solusi terbaik, berfungsi di semua browser .. bahkan di seluler.

<div class="btn" id="s_photo">Upload</div>

<input type="file" name="s_file" id="s_file" style="opacity: 0;">';

<!--jquery-->

<script>
    $("#s_photo").click(function() {
        $("#s_file").trigger("click");
    });
</script>

Menyembunyikan jenis file input menyebabkan masalah dengan browser, opacity adalah solusi terbaik karena tidak bersembunyi, hanya tidak muncul. :)

Pessa
sumber
1
Anda harus menyebutkan bahwa ini membutuhkan referensi jquery.
Brino
Opasitas melibatkan konsep yang sama sekali tidak terkait - Anda hanya beruntung jika tidak memengaruhi tata letak Anda dengan elemen "tembus pandang". Elemen tersebut harus ada, tetapi tidak terlihat, jadi visibility:hiddenharus menjadi pilihan yang lebih baik.
conny
visibility: hiddenmasih mempengaruhi tata letak. display: noneadalah apa yang kamu inginkan.
Stommestack
1

Tidak ada cara lintas browser untuk melakukannya, demi alasan keamanan. Apa yang biasanya dilakukan orang adalah melapisi file input di atas sesuatu yang lain dan mengatur visibilitasnya menjadi tersembunyi sehingga dipicu sendiri. Info selengkapnya di sini.

Alex Turpin
sumber
2
OP berbicara tentang <input type="file">, bukan <select>.
Bojangles
Bukan masalah. Saya telah melakukannya sendiri sebelumnya. Menanggapi suntingan Anda, ada adalah cara untuk melakukannya; dengan memicu event klik elemen dengan jQuery $.click().
Bojangles
1
@JamWaffles oke itu aneh. Saya ingat dengan jelas menghabiskan satu hari penuh untuk ini beberapa minggu yang lalu. Itu tidak bekerja di Firefox dan IE afair. Aku ingin tahu apa kesepakatannya ...
Alex Turpin
Ingin tahu. Saya memiliki JSFiddle dalam jawaban saya yang berfungsi dengan FF. Saya tidak dapat menguji di IE (saya menggunakan Linux), jadi saya tidak tahu apakah itu masih akan muntah.
Bojangles
2
Usaha penelitian yang bagus di sana! Jika saya membayar sepeser pun setiap kali pengembang web harus meretas beberapa perilaku yang cukup normal menjadi sesuatu, saya akan menjadi kaya raya.
Bojangles
1

Pastikan Anda menggunakan binding untuk mendapatkan props komponen di REACT

class FileUploader extends Component {
  constructor (props) {
    super(props);
    this.handleClick = this.handleClick.bind(this);
  }
   onChange=(e,props)=>{
    const files = e.target.files;
    const selectedFile = files[0];
    ProcessFileUpload(selectedFile,props.ProgressCallBack,props.ErrorCallBack,props.CompleatedCallBack,props.BaseURL,props.Location,props.FilesAllowed);
  }
   handleClick = () => {
    this.refs.fileUploader.click();
  }
  render()
  {
  return(
      <div>
        <button type="button" onClick={this.handleClick}>Select File</button>  
        <input type='file' onChange={(e)=>this.onChange(e,this.props)} ref="fileUploader" style={{display:"none"}} />
      </div>)
  }
}
m-farhan
sumber
0

Menggunakan jQuery Anda dapat memanggil click()untuk mensimulasikan klik.

pdubs
sumber
0

Ini berhasil untuk saya:

$('#fileInput').val('');
dileepar.dll
sumber
0

Bagi mereka yang menginginkan hal yang sama tetapi menggunakan React

openFileInput = () => {
    this.fileInput.click()
}

<a href="#" onClick={this.openFileInput}>
    <p>Carregue sua foto de perfil</p>
    <img src={img} />
</a>
<input style={{display:'none'}} ref={(input) => { this.fileInput = input; }} type="file"/>
Vinicius Lima
sumber
0
<div id="uploadButton">UPLOAD</div>
<form action="[FILE_HANDLER_URL]" style="display:none">
     <input id="myInput" type="file" />
</form>
<script>
  const uploadButton = document.getElementById('uploadButton');
  const myInput = document.getElementById('myInput');

  uploadButton.addEventListener('click', () => {
    myInput.click();
  });
</script>
yairniz
sumber