Entrée de fichier de déclenchement jQuery


163

J'essaie de déclencher une boîte de téléchargement (bouton Parcourir) en utilisant jQuery.
La méthode que j'ai essayée maintenant est:

$('#fileinput').trigger('click');   

Mais cela ne semble pas fonctionner. Veuillez aider. Je vous remercie.


Vous pouvez essayer quelque chose comme ça à la place.
Kirtan

19
Il n'y a aucun moyen de faire ça? Comme c'est déprimant.
Marcus Downing

Déprimant en effet, et il est déclenché par un «clic», sérieusement? Je préfère de loin Flash / AS3, avec son API étroite et son modèle de sécurité solide qui permet uniquement à FileReference.browse d'être appelé à partir d'un gestionnaire d'événements d'entrée initié par l'utilisateur. De plus, l'entrée de fichier HTML est moche et non stylable (c'est juste une balise d'entrée, donc pour la séparation du contenu et du style), vous devez donc créer un nouveau bouton `` parcourir '', qui est également activé par un événement de clic ... que vous devez transmettre à l'entrée du fichier en un clic ... ce qui peut conduire à une récursion infinie en fonction du placement des éléments et de la spécificité de la délégation d'événements.
Triynko

Malheureusement, l'utilisation de Flash devient de moins en moins viable, compte tenu de ses problèmes de sécurité constants et de la montée des bloqueurs de contenu.
Tim

Réponses:


195

Cela est dû à une restriction de sécurité.

J'ai découvert que la restriction de sécurité est uniquement lorsque le <input type="file"/>est défini sur display:none;ou est visbilty:hidden.

J'ai donc essayé le positionner en dehors de la fenêtre en définissant position:absoluteet top:-100px;et cela fonctionne le tour est joué.

voir http://jsfiddle.net/DSARd/1/

appelez ça un hack.

J'espère que cela fonctionne pour vous.


4
ne fonctionne pas dans ff 3.6. fonctionne en chrome et même en ie 8 cependant :)
AyKarsi

4
Existe-t-il une documentation sur msdn concernant la restriction de sécurité?
eomeroff

2
Fonctionne très bien. En tout cas, je pense que c'est un ensemble plus sûr left: -100px;. Vous ne savez jamais combien de temps peut durer une page
Alter Lagos

+1 C'est la vraie réponse (et une bonne solution). Quelqu'un aurait-il un lien vers la documentation où cela est explicitement indiqué?
kontur

9
vous pouvez également simplement définir l'opacité sur 0
Stuart

109

cela a fonctionné pour moi:

JS:

$('#fileinput').trigger('click'); 

HTML:

<div class="hiddenfile">
  <input name="upload" type="file" id="fileinput"/>
</div>

CSS:

.hiddenfile {
 width: 0px;
 height: 0px;
 overflow: hidden;
}

>>> Un autre qui fonctionne Cross-Browser: <<<

L'idée est que vous superposiez un énorme bouton "Parcourir" invisible sur votre bouton personnalisé. Ainsi, lorsque l'utilisateur clique sur votre bouton personnalisé, il clique en fait sur le bouton "Parcourir" du champ de saisie natif.

JS Fiddle: http://jsfiddle.net/5Rh7b/

HTML:

<div id="mybutton">
  <input type="file" id="myfile" name="upload"/>
  Click Me!
</div>

CSS:

div#mybutton {

  /* IMPORTANT STUFF */
  overflow: hidden;
  position: relative;   

  /* SOME STYLING */
  width:  50px;
  height: 28px;
  border: 1px solid green;
  font-weight: bold
  background: red;
}

div#mybutton:hover {
  background: green;
}

input#myfile {
  height: 30px;
  cursor: pointer;
  position: absolute;
  top: 0px;
  right: 0px;
  font-size: 100px;
  z-index: 2;

  opacity: 0.0; /* Standard: FF gt 1.5, Opera, Safari */
  filter: alpha(opacity=0); /* IE lt 8 */
  -ms-filter: "alpha(opacity=0)"; /* IE 8 */
  -khtml-opacity: 0.0; /* Safari 1.x */
  -moz-opacity: 0.0; /* FF lt 1.5, Netscape */
}

JavaScript:

$(document).ready(function() {
    $('#myfile').change(function(evt) {
        alert($(this).val());
    });
});

Il y a un défaut, si vous élargissez le bouton, alors dans IE9 / 10, le bouton de téléchargement invisible est composé du bouton droit et d'un champ de texte gauche. Sur ce, vous devez double-cliquer. Dans ce cas, essayez de définir la taille de la police encore plus grande que 100px;
yunzen

Cela fonctionne même dans Chrome 53. Cependant, il heightest suggéré de passer àheight: 100%
Raptor

Le second fonctionne même dans Safari sur iOS. Très agréable!
Jannis

71

Vous pouvez utiliser l'élément LABEL ex.

<div>
    <label for="browse">Click Me</label>
    <input type="file" id="browse" name="browse" style="display: none">//
</div>

Cela déclenchera le fichier d'entrée


5
Pourquoi n'est-ce pas la réponse acceptée? C'est le moyen le plus simple qui ne nécessite aucun javascript génial.
tomitrescak

@tomitrescak l'OP n'attend pas la meilleure réponse.
Mahi

9
Gardez à l'esprit que la réponse a été publiée 7 ans après la soumission de la question.

1
Meilleure réponse en 2018 aussi.
masoomyf

1
Meilleure réponse pour 2019 aussi;)
guillaumepotier

17

Je le fais fonctionner (= testé) dans IE8 +, FF récent et chrome:

$('#uploadInput').focus().trigger('click');

La clé se concentre avant de déclencher le clic (sinon Chrome l'ignore).

Remarque: vous devez avoir votre entrée affichée et visible (comme dans, pas display:noneet non visibility:hidden). Je suggère (comme beaucoup d'autres l'ont fait auparavant) de positionner absolument l'entrée et de la jeter hors de l'écran.

#uploadInput {
    position: absolute;
    left: -9999px;
}

1
+1 pour ça. J'ai également remarqué que vous pouvez masquer l'élément environnant mais pas le bouton d'entrée de fichier, puis afficher l'élément environnant, focaliser le bouton, l'activer, puis masquer le bouton.
Stevo

10

Regarde mon violon.

http://jsfiddle.net/mohany2712/vaw8k/

.uploadFile {
  visibility: hidden;
}

#uploadIcon {
  cursor: pointer;
}
<body>
  <div class="uploadBox">
    <label for="uploadFile" id="uploadIcon">
      <img src="http://upload.wikimedia.org/wikipedia/commons/thumb/3/34/Icon_-_upload_photo_2.svg/512px-Icon_-_upload_photo_2.svg.png"  width="20px" height="20px"/>
    </label>
    <input type="file" value="upload" id="uploadFile" class="uploadFile" />
  </div>
</body>


9

adardesign l'a cloué sur le fait que l'élément d'entrée du fichier était ignoré lorsqu'il est masqué. J'ai également remarqué que de nombreuses personnes changeaient la taille de l'élément à 0 ou le poussaient hors des limites avec des ajustements de positionnement et de débordement. Ce sont toutes de bonnes idées.
Une autre façon qui semble également fonctionner parfaitement est de simplement définir l'opacité sur 0 . Ensuite, vous pouvez toujours simplement définir la position pour l'empêcher de compenser d'autres éléments comme le fait hide. Il semble juste un peu inutile de déplacer un élément de près de 10K pixels dans n'importe quelle direction.

Voici un petit exemple pour ceux qui en veulent un:

input[type='file']{
    position:absolute;
    opacity:0;
    /* For IE8 "Keep the IE opacity settings in this order for max compatibility" */
    -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
    /* For IE5 - 7 */
    filter: alpha(opacity=0);
}

7

Par simple curiosité, vous pouvez faire quelque chose comme vous le souhaitez en créant dynamiquement un formulaire de téléchargement et un fichier d'entrée, sans l'ajouter à l'arborescence DOM:

$('.your-button').on('click', function() {
    var uploadForm = document.createElement('form');
    var fileInput = uploadForm.appendChild(document.createElement('input'));

    fileInput.type = 'file';
    fileInput.name = 'images';
    fileInput.multiple = true;

    fileInput.click();
});

Pas besoin d'ajouter le uploadForm au DOM.


1
MERCI! Je cherchais ça depuis 20 minutes!
Labo

5

Code correct:

<style>
    .upload input[type='file']{
        position: absolute;
        float: left;
        opacity: 0; /* For IE8 "Keep the IE opacity settings in this order for max compatibility" */
        -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; /* For IE5 - 7 */
        filter: alpha(opacity=0);
        width: 100px; height: 30px; z-index: 51
    }
    .upload input[type='button']{
        width: 100px;
        height: 30px;
        z-index: 50;
    }
    .upload input[type='submit']{
        display: none;
    }
    .upload{
        width: 100px; height: 30px
    }
</style>
<div class="upload">
    <input type='file' ID="flArquivo" onchange="upload();" />
    <input type="button" value="Selecionar" onchange="open();" />
    <input type='submit' ID="btnEnviarImagem"  />
</div>

<script type="text/javascript">
    function open() {
        $('#flArquivo').click();
    }
    function upload() {
        $('#btnEnviarImagem').click();
    }
</script>

4

C'est exprès et par conception. C'est un problème de sécurité.


4

En fait, j'ai découvert une méthode très simple pour cela, à savoir:

$('#fileinput').show().trigger('click').hide();   

De cette façon, votre champ de saisie de fichier peut afficher la propriété css sur aucun et gagner la transaction :)


il pourrait feuilleter sur l'écran de la machine la plus lente. Pas une solution optimale
Dmitry Efimenko

4

Il est trop tard pour répondre mais je pense que cette configuration minimale fonctionne le mieux. Je recherche également la même chose.

  <div class="btn-file">
     <input type="file" class="hidden-input">
     Select your new picture
  </div>

// css

.btn-file {
  display: inline-block;
  padding: 8px 12px;
  cursor: pointer;
  background: #89f;
  color: #345;
  position: relative;
  overflow: hidden;
}

.btn-file input[type=file] {
  position: absolute;
  top: 0;
  right: 0;
  min-width: 100%;
  min-height: 100%;
  filter: alpha(opacity=0);
  opacity: 0;
  cursor: inherit;
  display: block;
}

jsbin

Démo des boutons d'entrée du fichier bootstrap


il n'est jamais
trop

Quelques années plus tard, la meilleure réponse à l'OMI
DimmuR

4

C'est une question très ancienne, mais malheureusement, ce problème est toujours d'actualité et nécessite une solution.

La solution (étonnamment simple) que j'ai trouvée est de "cacher" le champ d'entrée du fichier réel et de l'envelopper avec une balise LABEL (peut être basée sur Bootstrap et HTML5, pour une amélioration).

See here:Exemple de code ici

De cette façon, le champ d'entrée du fichier réel est invisible et tout ce que vous voyez est le "bouton" personnalisé qui est en fait un élément LABEL modifié. Lorsque vous cliquez sur cet élément LABEL, la fenêtre de sélection d'un fichier apparaît et le fichier que vous choisissez ira dans le champ de saisie du fichier réel.

En plus de cela, vous pouvez manipuler l'apparence et le comportement à votre guise (par exemple: obtenir le nom du fichier sélectionné à partir du fichier d'entrée, après l'avoir sélectionné, et l'afficher quelque part. L'élément LABEL ne le fait pas automatiquement, Bien sûr, je le mets généralement à l'intérieur du LABEL, comme contenu textuel).

Attention cependant! La manipulation de l'apparence et du comportement de ceci est limitée à tout ce que vous pouvez imaginer et penser. ;-) ;-)


3

J'ai réussi avec un simple $ (...). Click (); avec JQuery 1.6.1


1
Hmm curieux de savoir comment vous avez fait cela, sur mon site Web (www.iscriptdesign.com) faire un $ ('file: input'). Click () ne fait rien, ni $ ('file: input'). Trigger (' Cliquez sur');
dr jerry

Voici l'exemple complet: <input type = "file" id = "picBrowse" ... puis $ ('# picBrowse'). Click ();
Valentin Galea

J'ai testé sur cr (je ne sais pas quelle version) sur mac os, fonctionne sur FF 4 sur XP cependant. Merci!
dr jerry

3

ou bien simplement

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

2

J'ai eu des problèmes avec la validation personnalisée côté client <input type="file"/>pendant l'utilisation d'un faux bouton pour le déclencher et la solution de @Guillaume Bodi a fonctionné pour moi (également avec opacity: 0;sur chrome)

$("#MyForm").on("click", "#fake-button", function () {
        $("#uploadInput").focus().trigger("click");
    });

et style css pour l'entrée de téléchargement

#uploadInput {
opacity: 0.0; 
filter: alpha(opacity=0); /* IE lt 8 */
-ms-filter: "alpha(opacity=0)"; /* IE 8 */
-khtml-opacity: 0.0; /* Safari 1.x */
-moz-opacity: 0.0;
}

1

Essayez ceci, c'est un hack. la position: absolue est pour Chrome et le déclencheur («changement») est pour IE.

var hiddenFile = $("<input type=\"file\" name=\"file\" id=\"file1\" style=\"position:absolute;left:-9999px\" />");
$('body').append(hiddenFile);

$('#aPhotoUpload').click(function () {
    hiddenFile.trigger('click');
    if ($.browser.msie)
        hiddenFile.trigger('change');
});

hiddenFile.change(function (e) {
    alert('TODO');
});

Notez que $.browserc'est obsolète dans les nouvelles versions de jQuery
Kevin Beal

1

Mon problème était un peu différent sur iOS 7. Il s'avère que FastClick posait des problèmes. Tout ce que j'avais à faire était d'ajouter class="needsclick"à mon bouton.


0

C'est probablement la meilleure réponse, en gardant à l'esprit les problèmes entre navigateurs.

CSS:

#file {
  opacity: 0;
  width: 1px;
  height: 1px;
}

JS:

$(".file-upload").on('click',function(){
   $("[name='file']").click();
});

HTML:

<a class="file-upload">Upload</a>
<input type="file" name="file">

0

Je pense que je comprends votre problème, car j'ai un similaire. Donc, la balise <label>a l'attribut pour, vous pouvez utiliser cet attribut pour lier votre entrée avec type = "file". Mais si vous ne voulez pas l'activer en utilisant cette étiquette parce que certaines règles de votre mise en page, vous pouvez faire comme ceci.

$(document).ready(function(){
  var reference = $(document).find("#main");
  reference.find(".js-btn-upload").attr({
     formenctype: 'multipart/form-data'
  });
  
  reference.find(".js-btn-upload").click(function(){
    reference.find("label").trigger("click");
  });
  
});
.hide{
  overflow: hidden;
  visibility: hidden;
  /*Style for hide the elements, don't put the element "out" of the screen*/
}

.btn{
  /*button style*/
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script>
<div id="main">
<form enctype"multipart/formdata" id="form-id" class="hide" method="post" action="your-action">
  <label for="input-id" class="hide"></label>
  <input type="file" id="input-id" class="hide"/>
</form>

<button class="btn js-btn-upload">click me</button>
</div>

Bien sûr, vous allez l'adapter à vos propres fins et mise en page, mais c'est le moyen le plus simple que je connaisse pour le faire fonctionner !!


-1

Sur la base de la réponse de Guillaume Bodi, j'ai fait ceci:

$('.fileinputbar-button').on('click', function() {
    $('article.project_files > header, article.upload').show();
    $('article.project_files > header, article.upload header').addClass('active');
    $('.file_content, article.upload .content').show();
    $('.fileinput-button input').focus().click();
    $('.fileinput-button').hide();
});

ce qui signifie qu'il est masqué au départ, puis affiché pour le déclencheur, puis à nouveau masqué immédiatement.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.