Attiva programmaticamente la finestra di dialogo "seleziona file"


100

Ho un elemento di input di file nascosto. È possibile attivare la sua finestra di dialogo Seleziona file dall'evento clic di un pulsante?

Risposte:


146

Se stai cercando di avere il tuo pulsante per caricare un file invece di usarlo <input type="file" />, puoi fare qualcosa come:

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

Nota che ho usato visibility: hidden, invece di display: none. Non è possibile chiamare l'evento clic su un input di file non visualizzato.


Semplice per i casi di base, ma non compatibile con molti browser. Si noti che è un'idea molto migliore combinare questa soluzione con la sovrapposizione dell'elemento di input del file su un pulsante a opacità: 0, come è stato menzionato nella risposta di Xeon06.
SquareCat

10
Aggiornamento: nei browser moderni è possibile fare clic su un input che non è nemmeno nel DOM. Eccezionale!
Adria

7
Ho appena provato click()un display:noneinput e ha funzionato
Daniel Cheung,

15
Sì, qui nell'anno 2015, click()su un elemento con display: noneopere! ;) Come sono cambiate le cose negli ultimi quattro anni.
ffxsam

Puoi usare l' hiddenattributo invece style="visibility:hidden": <input id="myInput" type="file" hidden>( w3schools.com/tags/att_global_hidden.asp )
cespon

114

Alla maggior parte delle risposte qui mancano informazioni utili:

Sì, puoi fare clic in modo programmatico sull'elemento di input utilizzando jQuery / JavaScript, ma solo se lo fai in un gestore di eventi che appartiene a un evento CHE È STATO AVVIATO DALL'UTENTE!

Quindi, ad esempio, non accadrà nulla se tu, lo script, fai clic sul pulsante in modo programmatico in un callback ajax, ma se inserisci la stessa riga di codice in un gestore di eventi che è stato generato dall'utente, funzionerà.

PS La debugger;parola chiave interrompe la finestra di navigazione se è prima del clic programmatico ... almeno in Chrome 33 ...


come giustamente menziona @LouisBataillard: non solo il gestore di eventi originale deve essere avviato dall'utente; deve essere specificamente un evento clic. Ecco un violino che ha fornito per dimostrarlo: link
Souhaieb Besbes

1
puoi fare clic su qualcosa che viene generato dinamicamente. in jquery, cioè$(staticElementParent).on("click", "dynamicChild", function(){})
Daniel Cheung,

1
GRAZIE!!!! Ho testato tutte queste risposte nella console javascript e sono impazzito!
jdkealy

8
Ho lottato per mezz'ora con la richiesta di programmazione di una finestra di input di file. NESSUN ALTRO ha dichiarato che è impossibile se l'evento non viene avviato dall'utente ... ti meriti molto +1.
Umagon

1
A partire da Chrome 62, la debugger;parola chiave non interrompe più il clic programmatico
Chris W.

62

Solo per la cronaca, esiste una soluzione alternativa che non richiede javascript. È un po 'un trucco, sfruttando il fatto che facendo clic su un'etichetta si pone l'accento sull'input associato.

Hai bisogno di un <label>con un forattributo appropriato (punta all'input), opzionalmente in stile come un pulsante (con bootstrap, usa btn btn-default). Quando l'utente fa clic sull'etichetta, si apre la finestra di dialogo, esempio:

<!-- 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" />


2
Mi piace questo, non voglio includere jQuery completo nel mio progetto Angular, funziona bene :)
Starscream1984

1
questo comportamento è affidabile in tutti i browser moderni?
JoshuaDavid

Funziona senza alcun JS, utilizzando il comportamento del browser nativo. In combinazione con gli eventi onDrop, l'implementazione di un caricamento di file ricco di funzionalità funziona alla grande!
Yanick Rochon

Ho dovuto giocherellare con il CSS ma poi ha funzionato - vale a dire la visibilità dell'input del file con "display: none" non è ok in tutti i browser. (Ma è possibile utilizzare l'opacità di 0, ecc.)
driftcatcher

13

Non sono sicuro di come i browser gestiscano i clic sugli type="file"elementi (problemi di sicurezza e tutto il resto), ma dovrebbe funzionare:

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

Ho testato questo JSFiddle in Chrome, Firefox e Opera e mostrano tutti la finestra di dialogo di ricerca dei file.


5
Questo sembra funzionare solo quando l'evento "chiamante" è esso stesso un evento clic. Ad esempio, non sembra essere possibile aprire la finestra di dialogo del file in base a un hoverevento: jsfiddle.net/UQfaZ/1
Louis B.

Sai come questo può essere testato con Selenio se l'ingresso non è nel DOM?
Sebastien Lorber

4

Mi avvolgo il input[type=file]in un tag label, quindi lo stile labeldi vostro gradimento, e nascondere il 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>

Soluzione puramente CSS.


Basta impostare <input type="file" hidden>per eliminare la necessità di applicare uno stile CSS.
Sylvain Lesage

3

Nativamente l'unico modo è creare un <input type="file">elemento e quindi simulare un clic, sfortunatamente.

C'è un piccolo plugin (plug senza vergogna) che ti toglierà il dolore di doverlo fare tutto il tempo: 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
        })
    })

3

La soluzione migliore, funziona in tutti i browser .. anche su cellulare.

<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>

Nascondere il tipo di file di input causa problemi con i browser, l'opacità è la soluzione migliore perché non si nasconde, semplicemente non si mostra. :)


1
dovresti menzionare che questo richiede un riferimento jquery.
Brino

L'opacità implica un concetto totalmente estraneo: sei solo fortunato se non influisce sul tuo layout con un elemento "trasparente". L'elemento dovrebbe essere lì, ma non visibile, quindi visibility:hiddendovrebbe essere una scelta migliore.
conny

visibility: hiddeninfluisce ancora sul layout. display: noneè quello che vuoi.
stommestack

1

Non esiste un modo cross browser per farlo, per motivi di sicurezza. Quello che le persone di solito fanno è sovrapporre il file di input a qualcos'altro e impostarne la visibilità su nascosto in modo che venga attivato da solo. Maggiori info qui.


2
L'OP sta parlando <input type="file">, no <select>.
Bojangles

Non è un problema. L'ho già fatto prima. In risposta alla sua modifica, non v'è un modo per farlo; attivando l'evento click dell'elemento con jQuery $.click().
Bojangles

1
@ JamWaffles ok, è strano. Ricordo chiaramente di aver passato un'intera giornata su questo alcune settimane fa. Non ha funzionato in Firefox e IE afair. Mi chiedo quale fosse l'accordo ...
Alex Turpin

Curioso. Ho un JSFiddle nella mia risposta che funziona con FF. Non posso testare in IE (sono su Linux), quindi non so se continuerà a vomitare.
Bojangles

2
Buon lavoro di ricerca lì! Se vado un centesimo per ogni volta che gli sviluppatori web dovessero modificare un comportamento abbastanza normale in qualcosa, sarei un ricco schifoso.
Bojangles

1

Assicurati di utilizzare l'associazione per ottenere gli oggetti di scena del componente in 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>)
  }
}


0

Questo ha funzionato per me:

$('#fileInput').val('');

0

Per coloro che vogliono lo stesso ma utilizzano 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"/>

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>
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.