Boîte de dialogue Ouvrir un fichier en JavaScript

109

J'ai besoin d'une solution pour afficher la boîte de dialogue d'ouverture de fichier en HTML tout en cliquant sur un fichier div. La boîte de dialogue d'ouverture de fichier doit s'ouvrir lorsque l'utilisateur divclique sur.

Je ne souhaite pas afficher la zone du fichier d'entrée dans le cadre d'une page HTML. Il doit être affiché dans une boîte de dialogue séparée, qui ne fait pas partie de la page Web.

Arche
la source
4
Une alerte n'est pas un fichier-dialogue? - Pouvez-vous clarifier ce que vous demandez?
LiamB
3
je pense qu'il dit qu'il veut le popup standard "open file"
Valentin Rocher
1
J'ai besoin d'ouvrir la boîte de dialogue de fichier lorsqu'un div est cliqué. il doit être comme une alerte qui ne fait pas partie de la page Web
ArK

Réponses:

52

En voici une belle

Démo Fine Uploader

C'est un <input type='file' />contrôle en soi. Mais un div est placé dessus et des styles css sont appliqués pour obtenir cette sensation. L'opacité du contrôle de fichier est définie sur 0 pour qu'il apparaisse que la fenêtre de dialogue s'ouvre en cliquant sur le div.

rahul
la source
1
existe-t-il un moyen de contrôler les fichiers affichés par javascript ... disons que je voulais ouvrir la boîte de dialogue de fichier et que je voulais juste afficher l'extension de fichier avec .pdf ..
Ajax3.14
1
@ Ajax3.14 nouveaux navigateurs a l'objet FileReader, les anciens navigateurs doivent utiliser la valeur et rechercher l'extension de fichier.
Vicary
2
@ Ajax3.14 Pas besoin d'utiliser FileReader ou d'analyser les extensions. De nombreux navigateurs prennent en charge l'attribut d'acceptation sur les entrées de fichier. Cela vous permet de limiter les types de fichiers affichés dans la boîte de dialogue du navigateur de fichiers. Fine Uploader permet d'accéder à cette fonctionnalité via la propriété acceptFiles de l'option de validation. Voir la section de validation de la documentation des options pour plus de détails. Notez que l'attribut accept n'est pas pris en charge dans IE9 ou une version antérieure.
Ray Nicholus
1
comment se fait-il que ce soit bon? c'est une bonne pratique du tout? ne devrait pas être quelque chose comme ceci: stackoverflow.com/a/18659941/915865 ?
Kat Lim Ruiz
1
@KatLimRuiz Non, la réponse à laquelle vous avez lié n'est pas une bonne solution. Cela entraînera IE pour générer une erreur si vous finissez par soumettre le formulaire associé par programme également.
Ray Nicholus
77

    $("#logo").css('opacity','0');
    
    $("#select_logo").click(function(e){
       e.preventDefault();
       $("#logo").trigger('click');
    });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a href="#" id="select_logo">Select Logo</a> <input type="file" id="logo">

pour IE, ajoutez ceci:

$("#logo").css('filter','alpha(opacity = 0');
Somwang Souksavatd
la source
3
Pourquoi renvoyez-vous false dans le gestionnaire de clics #select_logo?
Sethish
4
Cela ne produirait pas d'erreur 404, il essaierait simplement de naviguer vers la page actuelle, avec le # ajouté à la fin. Ce qui ferait sauter la page vers le haut. Donc c'est bon d'être là, juste pour une raison différente :)
manavo
3
Bien que je ne l'ai pas suffisamment testé, "visibilité: hidden;" semble plus compatible. De plus, malgré l'opacité: 0 un événement de clic se déclenchera si l'élément "invisible" a cliqué, alors que visibilité: hidden ne le sera pas.
Aron
MDN indique que document.getElementById("logo").click()c'est suffisant. Ils montrent également une autre façon "Drag & Drop". developer.mozilla.org/en-US/docs/Web/API/File/…
Eric
2
Vous devriez le convertir en Javascript normal, JQuery n'est pas logique à utiliser sur un si petit projet ^ _ ^
Mister SirCode
57

Je ne sais pas pourquoi personne ne l'a signalé, mais voici un moyen de le faire sans Javascript et il est également compatible avec n'importe quel navigateur.


EDIT: Dans Safari, le inputest désactivé lorsqu'il est masqué avec display: none. Une meilleure approche serait d'utiliser position: fixed; top: -100em.


<label>
  Open file dialog
  <input type="file" style="position: fixed; top: -100em">
</label>

Si vous préférez, vous pouvez aller dans le "bon sens" en utilisant fordans le labelpointant vers idl'entrée comme ceci:

<label for="inputId">file dialog</label>
<input id="inputId" type="file" style="position: fixed; top: -100em">
JP de la Torre
la source
4
cela fonctionne comme un charme, cependant, voici quelques recommandations: 1. la <input>balise doit avoir un nameattribut; 2. si l' forattribut est spécifié, <input>la balise de fichier nécessitera un id.
Raptor
5
Simplicity is the ultimate sophistication
ncubica
2
génial! cela fonctionne comme un charme même avec une image de fond ou faisant que l'étiquette reçoive un clic javascript déclenché. Merci!
Leo Nomdedeu
2
BTW, quelqu'un a pointé une capture avec cette solution, dans Safari, les entrées masquées avec display: nonesont désactivées. La solution de contournement utilise une approche différente pour masquer l'entrée. Je mettrai à jour la réponse pour refléter cela.
JP de la Torre
1
@JPdelaTorre Ce serait bien mieux si vous utilisiez opacity: 0 à la place pour masquer l'entrée.
Adrian
39

En fait, vous n'avez pas besoin de tout cela avec l'opacité, la visibilité, le <input>style, etc. Jetez un coup d'œil:

<a href="#">Just click me.</a>
<script type="text/javascript">
    $("a").click(function() {
        // creating input on-the-fly
        var input = $(document.createElement("input"));
        input.attr("type", "file");
        // add onchange handler if you wish to get the file :)
        input.trigger("click"); // opening dialog
        return false; // avoiding navigation
    });
</script>

Démo sur jsFiddle . Testé dans Chrome 30.0 et Firefox 24.0. Cela ne fonctionnait pas dans Opera 12.16, cependant.

Tigran Saluev
la source
3
Cela devrait être la bonne réponse. Pour une implémentation Javascript pur, vous n'avez pas besoin de modifier de code HTML.
Zhang Buzz
21
Question idiote, mais comment obtiendriez-vous le fichier choisi par la suite?
Jay Wick
2
Il s'agit d'une solution dangereuse qui peut entraîner des problèmes inattendus. Par exemple, certains navigateurs (tels que IE) peuvent empêcher l'envoi d'un formulaire par programme si l'entrée de fichier est également ouverte par programme. La meilleure façon de résoudre ce problème est d'utiliser CSS et non JavaScript.
Ray Nicholus
3
@Charleston Malheureusement, cela ne fonctionne pas dans certains navigateurs. Ils devraient le faire fonctionner cependant :)
Tigran Saluev
3
À partir de 2020, cette solution semble la plus agréable. Je l'ai testé sur BrowserStack dans Edge, Safari, Opera, Firefox et Chrome. Fonctionne dans chacun d'eux.
V. Rubinetti
14

C'est ce qui a le mieux fonctionné pour moi (testé sur IE8, FF, Chrome, Safari).

#file-input {
  cursor: pointer;
  outline: none;
  position: absolute;
  top: 0;
  left: 0;
  width: 0;
  height: 0;
  overflow: hidden;
  filter: alpha(opacity=0); /* IE < 9 */
  opacity: 0;
}
.input-label {
  cursor: pointer;
  position: relative;
  display: inline-block;
}
<label for="file-input" class="input-label">
  Click Me <!-- Replace with whatever text or icon you wish to use -->
  <input type="file" id="file-input">
</label>

Explication: J'ai positionné l'entrée de fichier directement au-dessus de l'élément sur lequel cliquer, de sorte que tout clic atterrirait soit sur celui-ci, soit sur son étiquette (ce qui fait apparaître la boîte de dialogue de téléchargement comme si vous aviez cliqué sur l'étiquette elle-même). J'ai eu quelques problèmes avec la partie bouton de l'entrée par défaut qui sortait du côté de l'étiquette, donc overflow: hiddensur l'entrée et display: inline-blocksur l'étiquette étaient nécessaires.

Chris
la source
1
Maximisez l'entrée et définissez l'opacité sur zéro. Cela fonctionne très bien!
Kinorsi
13

Que faire si javascript est désactivé sur la machine des clients? Utilisez la solution suivante pour tous les scénarios. Vous n'avez même pas besoin de javascript / jQuery. :

HTML

<label for="fileInput"><img src="File_upload_Img"><label>
<input type="file" id="fileInput"></label>

CSS

#fileInput{opacity:0}  
body{
    background:cadetblue;
}

Explication: for="Your input Id". Déclenche l'événement de clic par défaut par HTML. Donc, il déclenche par défaut l'événement de clic, pas besoin de jQuery / javascript. Si c'est simplement fait par HTML, pourquoi utiliser jQuery / jScript? Et vous ne pouvez pas dire si le client a désactivé JS. Votre fonctionnalité devrait fonctionner même si JS est désactivé.

JsFiddle de travail (vous n'avez pas besoin de JS, jquery)

Pratik
la source
3
Pourquoi le fond?
Solomon Ucko
12

Ajoutez d'abord les balises head :

<script>
   function showDialog(openFileDialog) {
       document.getElementById(openFileDialog).click();
   }
   function fileName(openFileDialog) {
       return document.getElementById(openFileDialog).value;
   }
   function hasFile(openFileDialog) {
       return document.getElementById(openFileDialog).value != "";
   }
   function fileNameWithoutFakePath(openFileDialog) {
       var fileName = document.getElementById(openFileDialog).value;
       return fileName.substr(fileName.lastIndexOf('\\') + 1);
   }
   function fakePathWithoutFileName(openFileDialog) {
       var fileName = document.getElementById(openFileDialog).value;
       return fileName.substr(0, fileName.lastIndexOf('\\'));
   }
</script>

si vous avez déjà des balises de script , ajoutez simplement ces fonctions ci-dessus.

Dans votre corps ou votre formulaire, ajoutez des balises:

<input type="file" style="display:none" id="yourDesiredOrFavoriteNameForTheNewOpenFileDialogInstance"/>

Peu importe où dans votre html, c'est comme si vous avez créé une nouvelle instance de type classe OpenFileDialog en tant que variable globale , dont le nom est l' id de l'élément, peu importe où dans votre code ou xaml, mais dans votre script ou code , vous ne pouvez pas taper son nom, puis lire une propriété ou appeler une fonction, car il existe des fonctions globales qui font celles qui ne sont pas définies dans l'élément input type = "file". Il vous suffit de donner à ces fonctions l'identifiant de l'entrée masquée type = "file" qui est le nom de l'instance OpenFileDialog sous forme de chaîne.

Pour vous faciliter la vie dans la création d'instances de dialogues de fichiers ouverts dans votre html, vous pouvez créer une fonction qui le fait:

function createAndAddNewOpenFileDialog(name) {
     document.getElementById("yourBodyOrFormId").innerHtml += "<input type='file' style='display:none' id='" + name + "'/>"
}

et si vous souhaitez supprimer la boîte de dialogue de fichier ouvert, vous pouvez créer et utiliser la fonction suivante:

function removeOpenFileDialog(name) {
    var html = document.getElementById("yourBodyOrFormId").innerHtml;
    html = html.replace("<input type='file' style='display:none' id='" + name + "'/>", "");
    document.getElementById("yourBodyOrFormId").innerHtml = html;
}

mais avant de supprimer la boîte de dialogue d'ouverture de fichier, assurez-vous qu'elle existe en créant et en utilisant la fonction suivante:

function doesOpenFileDialogExist(name) {
    return document.getElementById("yourBodyOrFormId").innerHtml.indexOf("<input type='file' style='display:none' id='" + name + "'/>") != -1
}

et si vous ne voulez pas créer et ajouter les boîtes de dialogue de fichier ouvert dans le corps ou les balises de formulaire dans le html, car il s'agit d'ajouter des entrées masquées type = "file" s, vous pouvez le faire dans le script en utilisant la fonction de création ci-dessus :

function yourBodyOrFormId_onload() {
    createAndAddNewOpenFileDialog("openFileDialog1");
    createAndAddNewOpenFileDialog("openFileDialog2");
    createAndAddNewOpenFileDialog("openFileDialog3");
    createAndAddNewOpenFileDialog("File Upload");
    createAndAddNewOpenFileDialog("Image Upload");
    createAndAddNewOpenFileDialog("bla");
    //etc and rest of your code
}

Assurez-vous que près de votre corps ou des balises de formulaire, vous avez ajouté:

onload="yourBodyOrFormId_onload()"

Vous n'avez pas à faire cette ligne ci-dessus, si vous l'avez déjà fait.

CONSEIL: Vous pouvez ajouter à votre projet ou site Web un nouveau fichier JScript, si vous ne l'avez pas encore fait, et dans ce fichier, vous pouvez mettre toutes les fonctions de dialogue de fichier ouvert à l'écart des balises de script et de la page HTML ou du formulaire Web, et utiliser les dans votre page de formulaire html ou Web à partir de ce fichier JScript, mais n'oubliez pas avant de lier la page de formulaire html ou Web au fichier JScript bien sûr. Vous pouvez le faire simplement en faisant glisser le fichier JScript sur votre page html dans la têteMots clés. Si votre page est un formulaire Web et non un simple HTML, et que vous n'avez pas de balises head, placez-la n'importe où pour qu'elle fonctionne. N'oubliez pas de définir la variable globale dans ce fichier JScript, dont la valeur sera votre corps ou l'identifiant de formulaire sous forme de chaîne. Après avoir lié le fichier JScript à votre page de formulaire html ou Web, vous pouvez charger l'événement de votre corps de formulaire, définir la valeur de cette variable sur votre corps ou votre identifiant de formulaire. Ensuite, dans le fichier JScript, vous n'avez plus à donner au document l'identifiant du corps ou de la forme d'une page, donnez-lui simplement la valeur de cette variable. Vous pouvez appeler cette variable bodyId ou formId ou bodyOrFormId ou tout autre nom de votre choix .

Bonne chance, mec!


la source
1
Il est préférable de ne pas modifier directement le innerHTML.
Solomon Ucko
9

Le moyen le plus simple:

#file-input {
  display: none;
}
<label for="file-input">
  <div>Click this div and select a file</div>
</label>
<input type="file" id="file-input"/>

Ce qui est important, l'utilisation de display: nonegarantit qu'aucune place ne sera occupée par l'entrée de fichier caché (ce qui se passe avec opacity: 0).

Karol Selak
la source
3

AFAIK vous avez toujours besoin d'un <input type="file">élément, alors vous pouvez utiliser certains des éléments de quirksmode pour le styliser

Dan F
la source
2

Le seul sans <input type="file">est en incorporant une animation flash transparente sur le div. Vous pouvez ensuite utiliser un événement de clic généré par l'utilisateur (conforme aux nouvelles règles de sécurité de Flash 10) pour déclencher un appel à FileReference.browse de flash .

Il offre une dépendance supplémentaire sur la manière quirksmode mais en retour, vous obtenez beaucoup plus d'événements (tels que des événements de progression intégrés).

Martijn Laarman
la source
-1

Peut utiliser

$('<input type="file" />').click()
Hamed Zakery Miab
la source
dans mon cas, cela provoque une redirection automatique vers la même page où l'événement de clic d'origine s'est produit - faisant recharger la page entière et perdre toutes les données précédemment entrées dans la page.
Muntasir