267 votes

En JavaScript, puis-je faire en sorte qu'un événement "clic" se déclenche de manière programmée pour un élément de saisie de fichier ?

J'aimerais faire en sorte qu'un événement de clic se déclenche sur un élément de la liste de contrôle. <input type="file"> de manière programmatique.

Le simple fait d'appeler click() ne semble rien faire ou, du moins, ne fait pas apparaître une boîte de dialogue de sélection de fichier.

J'ai essayé de capturer des événements en utilisant des écouteurs et en redirigeant l'événement, mais je n'ai pas réussi à faire en sorte que l'événement se produise réellement, comme si quelqu'un avait cliqué dessus.

2 votes

L'événement de clic que vous déclenchez doit être appelé au sein d'un événement de clic lancé par l'utilisateur, sinon cela ne fonctionnera pas.

261voto

Romas Points 1797

J'ai cherché une solution à ce problème toute la journée. Et voici les conclusions que j'ai tirées :

  1. Pour des raisons de sécurité, Opera et Firefox ne permettent pas de déclencher l'entrée de fichiers.
  2. La seule solution pratique consiste à créer une entrée de fichier "cachée" (en utilisant l'opacité, et non pas "caché" ou "affichage : none" ! De cette façon, le bouton est visible, mais lorsque l'utilisateur clique dessus, il active réellement l'entrée de fichier.

J'espère que cela vous aidera ! :)

<div style="display: block; width: 100px; height: 20px; overflow: hidden;">
<button style="width: 110px; height: 30px; position: relative; top: -5px; left: -5px;"><a href="javascript: void(0)">Upload File</a></button>
<input type="file" id="upload_input" name="upload" style="font-size: 50px; width: 120px; opacity: 0; filter:alpha(opacity: 0);  position: relative; top: -40px;; left: -20px" />
</div>

7 votes

Cette solution fonctionne très bien. Je ne sais pas pourquoi elle a été négligée et non évaluée. Ce n'est pas *exactement ce que la question demande, mais c'est une excellente solution. Avez-vous constaté une incompatibilité avec certains navigateurs ? Je n'ai pas le temps de me frayer un chemin à travers les plus de 10 versions de navigateurs pertinents pour les tester.

1 votes

Merci pour cette réponse, c'est génial :D

0 votes

Bonne solution. Fonctionne également sur le navigateur mobile Android.

81voto

Jason Bunting Points 27534

Vous ne pouvez pas faire cela dans tous les navigateurs, soi-disant IE fait le permettent, mais Mozilla et Opera ne le font pas.

Lorsque vous composez un message dans GMail, la fonction "joindre des fichiers" est mise en œuvre d'une manière pour IE et tout navigateur qui la prend en charge, et d'une autre manière pour Firefox et les navigateurs qui ne la prennent pas en charge.

Je ne sais pas pourquoi tu ne peux pas le faire, mais une chose qui est un risque pour la sécurité, et ce que vous n'êtes autorisé à faire dans aucun navigateur, est de définir par programme le nom du fichier sur l'élément HTML File.

1 votes

Drat. Je comprends bien que c'est exploitable. Est-ce que cela est documenté quelque part ? Je suppose que cela doit être mis en œuvre par chaque navigateur ?

0 votes

J'ai mis à jour ma réponse pour qu'elle soit plus correcte que la précédente - l'essentiel est le même, mais la clarification devrait aider un peu. Cet homme a rencontré le même problème : bytes.com/forum/thread542877.html

0 votes

Dieu merci, FF5 permet ce clic

68voto

Florin Mogos Points 499

Vous pouvez lancer click() sur n'importe quel navigateur mais certains navigateurs ont besoin que l'élément soit visible et focalisé. Voici un exemple en jQuery :

$('#input_element').show();
$('#input_element').focus();
$('#input_element').click();
$('#input_element').hide();

Il fonctionne avec le cache avant le click() mais je ne sais pas si cela fonctionne sans appeler la méthode show. Je n'ai jamais essayé cela sur Opera, j'ai testé sur IE/FF/Safari/Chrome et cela fonctionne. J'espère que cela vous aidera.

54 votes

Merci pour le partage. Au cas où vous ne le sauriez pas, vous pouvez utiliser le chaînage dans jQuery : $(...).show().focus().click().hide(); :)

1 votes

@pimvdb : d'après mes tests, votre solution ne fonctionne que sur Chrome.

1 votes

@Hoàng Long : Voulez-vous parler du chaînage ou de la solution de Florin Mogos ? Je ne pense pas que le chaînage fasse des différences inter-navigateurs.

30voto

C'EST POSSIBLE : Sous FF4+, Opera ?, Chrome : mais :

  1. inputElement.click() doit être appelé depuis le contexte d'action de l'utilisateur ! (pas le contexte d'exécution du script)

  2. <input type="file" /> devrait être visible ( inputElement.style.display !== 'none' ) (vous pouvez le cacher avec la visibilité ou autre, mais pas avec la propriété "display")

0 votes

Cela a résolu le problème pour moi. J'ai dû ajouter le javascript à la page onclick au lieu de se lier à l'événement.

1 votes

L'upvoting est la seule solution raisonnable. La méthode du débordement est moche.

0 votes

Ha ! Je savais que cela devait avoir un rapport avec le contexte ! J'avais observé qu'appeler inputElement.click() à partir d'un événement de frappe (raccourci pour joindre un fichier) a fonctionné, mais l'appeler dans un délai d'attente ou un rappel Ajax ne l'a PAS fait. Approuvé.

10voto

McTrafik Points 818

Pour ceux qui comprennent qu'il faut superposer un formulaire invisible sur le lien, mais qui sont trop paresseux pour écrire, je l'ai écrit pour vous. Enfin, pour moi, mais autant partager. Les commentaires sont les bienvenus.

HTML (quelque part) :

<a id="fileLink" href="javascript:fileBrowse();" onmouseover="fileMove();">File Browse</a>

HTML (Quelque chose dont vous ne vous souciez pas) :

<div id="uploadForm" style="filter:alpha(opacity=0); opacity: 0.0; width: 300px; cursor: pointer;">
    <form method="POST" enctype="multipart/form-data">
        <input type="file" name="file" />
    </form>
</div>

JavaScript :

function pageY(el) {
    var ot = 0;
    while (el && el.offsetParent != el) {
        ot += el.offsetTop ? el.offsetTop : 0;
        el = el.offsetParent;
    }
    return ot;
}

function pageX(el) {
    var ol = 0;
    while (el && el.offsetParent != el) {
        ol += el.offsetLeft ? el.offsetLeft : 0;
        el = el.offsetParent;
    }
    return ol;
}

function fileMove() {
    if (navigator.appName == "Microsoft Internet Explorer") {
        return; // Don't need to do this in IE. 
    }
    var link = document.getElementById("fileLink");
    var form = document.getElementById("uploadForm");
    var x = pageX(link);
    var y = pageY(link);
    form.style.position = 'absolute';
    form.style.left = x + 'px';
    form.style.top = y + 'px';
}

function fileBrowse() {
    // This works in IE only. Doesn't do jack in FF. :( 
    var browseField = document.getElementById("uploadForm").file;
    browseField.click();
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X