Programmgesteuert das Dialogfeld "Datei auswählen" auslösen

99

Ich habe ein verstecktes Dateieingabeelement. Ist es möglich, das Dialogfeld " Datei auswählen" über das Klickereignis einer Schaltfläche auszulösen ?

Tamakisquare
quelle

Antworten:

145

Wenn Sie eine eigene Schaltfläche zum Hochladen einer Datei haben möchten, anstatt diese zu verwenden <input type="file" />, können Sie Folgendes tun:

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

Beachten Sie, dass ich visibility: hiddenanstelle von verwendet habe display: none. Sie können das Klickereignis nicht für eine nicht angezeigte Dateieingabe aufrufen.

Mike Gwilt
quelle
Einfach für grundlegende Fälle, aber nicht kompatibel mit vielen Browsern. Bitte beachten Sie, dass es eine viel bessere Idee ist, diese Lösung mit der Überlagerung des Dateieingabeelements über eine Schaltfläche mit der Deckkraft 0 zu kombinieren, wie in der Antwort von Xeon06 erwähnt.
SquareCat
10
Update: In modernen Browsern können Sie auf eine Eingabe klicken, die sich nicht einmal im DOM befindet. Genial!
Adria
7
Ich habe gerade click()einen display:noneEingang anprobiert und es hat funktioniert
Daniel Cheung
15
Ja, hier im Jahr 2015, click()auf ein Element mit display: noneWerken! ;) Wie sich die Dinge in den letzten vier Jahren verändert haben.
ffxsam
Sie können hiddenstattdessen Attribut verwenden style="visibility:hidden": <input id="myInput" type="file" hidden>( w3schools.com/tags/att_global_hidden.asp )
Cespon
112

Den meisten Antworten fehlen nützliche Informationen:

Ja, Sie können programmgesteuert mit jQuery / JavaScript auf das Eingabeelement klicken, aber nur, wenn Sie dies in einem Ereignishandler tun, der zu einem Ereignis gehört, das vom Benutzer gestartet wurde!

So passiert beispielsweise nichts, wenn Sie als Skript programmgesteuert auf die Schaltfläche in einem Ajax-Rückruf klicken. Wenn Sie jedoch dieselbe Codezeile in einen vom Benutzer ausgelösten Ereignishandler einfügen, funktioniert dies.

PS Das debugger;Schlüsselwort unterbricht das Suchfenster, wenn es vor dem programmatischen Klick steht ... zumindest in Chrome 33 ...

Fazi
quelle
Wie @LouisBataillard zu Recht erwähnt: Der ursprüngliche Ereignishandler muss nicht nur vom Benutzer initiiert werden. Es muss speziell ein Klickereignis sein. Hier ist eine Geige, die er zur Verfügung gestellt hat, um dies zu demonstrieren: Link
Souhaieb Besbes
1
Sie können auf etwas klicken, das dynamisch generiert wird. in jquery, das heißt$(staticElementParent).on("click", "dynamicChild", function(){})
Daniel Cheung
1
DANKE!!!! Ich habe all diese Antworten in der Javascript-Konsole getestet und bin verrückt geworden!
jdkealy
8
Ich habe seit einer halben Stunde Probleme damit, programmgesteuert ein Dateieingabefenster aufzurufen. NOBODY ELSE gab an, dass es unmöglich ist, wenn das Ereignis nicht vom Benutzer gestartet wird ... Sie verdienen viel +1.
Umagon
1
Ab Chrome 62 debugger;stört das Schlüsselwort den programmatischen Klick nicht mehr
Chris W.
62

Nur für die Aufzeichnung gibt es eine alternative Lösung, die kein Javascript erfordert. Es ist ein bisschen wie ein Hack, der die Tatsache ausnutzt, dass das Klicken auf ein Etikett den Fokus auf die zugehörige Eingabe legt.

Sie benötigen ein Attribut <label>mit einem geeigneten forAttribut (zeigt auf die Eingabe), das optional wie eine Schaltfläche gestaltet ist (mit Bootstrap verwenden btn btn-default). Wenn der Benutzer auf die Beschriftung klickt, wird der Dialog geöffnet. Beispiel:

<!-- 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
quelle
2
Ich mag dieses, möchte nicht voll jQuery in mein Angular-Projekt aufnehmen, funktioniert gut :)
Starscream1984
1
Ist dieses Verhalten in allen modernen Browsern zuverlässig?
Joshua David
Dies funktioniert ohne jegliches JS unter Verwendung des nativen Browserverhaltens. In Verbindung mit onDrop-Ereignissen funktioniert die Implementierung eines funktionsreichen Datei-Uploads hervorragend!
Yanick Rochon
Ich musste mit dem CSS herumspielen, aber dann hat es funktioniert - nämlich die Sichtbarkeit der Dateieingabe mit "display: none" ist nicht in allen Browsern in Ordnung. (Aber Opazität von 0 usw. kann verwendet werden)
Driftcatcher
13

Ich bin nicht sicher, wie Browser mit Klicks auf type="file"Elemente umgehen (Sicherheitsbedenken und alles), aber das sollte funktionieren:

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

Ich habe diese JSFiddle in Chrome, Firefox und Opera getestet und alle zeigen den Dialog zum Durchsuchen von Dateien.

Bojangles
quelle
5
Dies scheint nur zu funktionieren, wenn das "aufrufende" Ereignis selbst ein Klickereignis ist. Zum Beispiel scheint es nicht möglich zu sein, den Dateidialog basierend auf einem hoverEreignis zu öffnen : jsfiddle.net/UQfaZ/1
Louis B.
Wissen Sie, wie dies mit Selen getestet werden kann, wenn sich der Eingang nicht im DOM befindet?
Sebastien Lorber
4

Ich wickle das input[type=file]in ein Etiketten-Tag ein, gestalte es dann labelnach Ihren Wünschen und verstecke das 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>

Rein CSS-Lösung.

Ponyboy
quelle
Stellen Sie einfach ein <input type="file" hidden>, um die Notwendigkeit zu beseitigen, einen CSS-Stil anzuwenden.
Sylvain Lesage
3

Nativ besteht der einzige Weg darin, ein <input type="file">Element zu erstellen und dann leider einen Klick zu simulieren.

Es gibt ein winziges Plugin (schamloses Plugin), das Ihnen die Mühe nimmt, dies ständig tun zu müssen: Dateidialog

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

Die beste Lösung funktioniert in allen Browsern .. auch auf Mobilgeräten.

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

Das Ausblenden des Eingabedateityps führt zu Problemen mit Browsern. Die Deckkraft ist die beste Lösung, da sie nicht ausgeblendet, sondern nur nicht angezeigt wird. :) :)

Pessa
quelle
1
Sie sollten erwähnen, dass dies eine Abfrage-Referenz erfordert.
Brino
Deckkraft beinhaltet ein völlig unabhängiges Konzept - Sie haben nur Glück, wenn es Ihr Layout mit einem "durchsichtigen" Element nicht beeinflusst. Das Element sollte vorhanden, aber nicht sichtbar sein, daher visibility:hiddensollte es eine bessere Wahl sein.
Conny
visibility: hiddenwirkt sich immer noch auf das Layout aus. display: noneist was du willst.
Stommestack
1

Aus Sicherheitsgründen gibt es keine browserübergreifende Methode. Normalerweise wird die Eingabedatei über etwas anderes gelegt und die Sichtbarkeit auf "Ausgeblendet" gesetzt, damit sie von selbst ausgelöst wird. Mehr Infos hier.

Alex Turpin
quelle
2
Das OP spricht <input type="file">nicht darüber <select>.
Bojangles
Kein Problem. Ich habe es selbst schon einmal gemacht. Als Reaktion auf Ihre Bearbeitung gibt es eine Möglichkeit, dies zu tun. durch Auslösen des Klickereignisses des Elements mit jQuery $.click().
Bojangles
1
@ JamWaffles okay, das ist komisch. Ich erinnere mich noch genau, wie ich vor ein paar Wochen einen ganzen Tag damit verbracht habe. In Firefox und IE afair hat es nicht funktioniert. Ich frage mich, was der Deal war ...
Alex Turpin
Neugierig. Ich habe eine JSFiddle in meiner Antwort, die mit FF funktioniert. Ich kann nicht im IE testen (ich bin unter Linux), daher weiß ich nicht, ob sich das noch ergibt.
Bojangles
2
Gute Forschungsanstrengungen dort! Wenn ich für jedes Mal einen Cent ausgeben würde, wenn Webentwickler ein ziemlich normales Verhalten in etwas hacken müssten, wäre ich dreckig reich.
Bojangles
1

Stellen Sie sicher, dass Sie die Bindung verwenden, um Komponenten-Requisiten in REACT abzurufen

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

Mit jQuery können Sie click()einen Klick simulieren.

pdubs
quelle
0

Das hat bei mir funktioniert:

$('#fileInput').val('');
Dileepar
quelle
0

Für diejenigen, die dasselbe wollen, aber React verwenden

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