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.

Alec Smart
la source
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.

adardesign
la source
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());
    });
});
traîneau
la source
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

Jhon Rey
la source
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;
}
Le puissant canard en caoutchouc
la source
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>

Mohan
la source
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);
}
eyegropram
la source
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.

Jairhumberto
la source
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>
Systèmes E9
la source
4

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

Chad Grant
la source
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 :)

skywlkr
la source
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

Natwar Singh
la source
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. ;-) ;-)

TheCuBeMan
la source
3

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

Valentin Galea
la source
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();
Otvazhnii
la source
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;
}
Amin K
la source
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');
});
thinpiglin
la source
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.

Dex
la source
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">
Eddsters
la source
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 !!

Leonardo Lindroth
la source
-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.

Stevo
la source