web-dev-qa-db-fra.com

Jquery: change l'événement en entrée du fichier IE

J'ai déjà regardé tout autour et je ne trouve pas de solution: j'ai un formulaire pour télécharger des fichiers et il devrait déclencher l'envoi après la sélection du fichier.

Sur FF/Chrome, il va très bien et envoie le formulaire après la sélection du fichier, mais je ne peux pas le faire sur ie.

Déjà essayé avec click/propertychange mais rien ne se passe. Un code que j'ai déjà essayé:

$("#attach").attr("onChange", "alert('I changed')");

$("#attach").live($.browser.msie? 'propertychange': 'change', function(e) { ... });

Avez-vous des suggestions à essayer?

Edit1: Je pense qu'il y a une information importante, ce fichier d'entrée, est créé à la volée, c'est pourquoi j'utilise .live () pour lier l'événement.

35
cmedeiros

Je sais que cela a plusieurs mois de retard, mais je viens de rencontrer exactement le même comportement dans IE7; dans tous les autres navigateurs, l'événement de modification pour les entrées de fichier se produit après la sélection du fichier. Dans IE7, cela ne se produit que si vous déclenchez à nouveau la sélection de fichier ou si le flou est activé.

Voici comment j'ai fini par le réparer:

var $input = $('#your-file-input-element');

var someFunction = function()
{
    // what you actually want to do
};

if ($.browser.msie)
{
    // IE suspends timeouts until after the file dialog closes
    $input.click(function(event)
    {
        setTimeout(function()
        {
            if($input.val().length > 0) {
              someFunction();
            }
        }, 0);
    });
}
else
{
    // All other browsers behave
    $input.change(someFunction);
}

Techniquement, vous pourriez/devriez filtrer la condition de hack uniquement sur IE7, car IE8 se comporte correctement lors de l'événement change, mais il a le même comportement que IE7 lorsqu'il suspend les délais d'attente lorsque le chrome lié au navigateur est visible O), donc ça marche comme-est.

40
Clint Tseng

C’est très tard, mais j’avais le même problème et je l’ai résolu en utilisant une balise stylisée <label> avec une solution de contournement légère pour Firefox.

http://jsfiddle.net/djibouti33/uP7A9/

Les objectifs:

  1. permettre à l'utilisateur de télécharger un fichier à l'aide du contrôle d'entrée standard de fichier html
  2. masquer le contrôle d'entrée de fichier html standard et appliquer son propre style
  3. après que l'utilisateur sélectionne le fichier à télécharger, soumettez automatiquement le formulaire

Les navigateurs:

  • Firefox, Chrome, IE8/9, Safari
  • IE7 ne fonctionnait pas, mais il se peut que vous ajoutiez ce navigateur à la solution de contournement décrite en bas.

La solution initiale:

  1. Cachez le fichier en le positionnant hors écran. Important de ne pas afficher: aucun, car certains navigateurs ne l’aimeront pas.
  2. Ajoutez un autre élément stylé à la page (lien, bouton). 
  3. Écoutez un clic sur cet élément, puis envoyez par programme un clic à l'entrée du fichier pour déclencher l'explorateur de fichiers natif.
  4. Écouter l'événement onchange de l'entrée de fichier (survient après qu'un utilisateur a choisi son fichier) 
  5. Soumettre le formulaire

Le problème:

  1. IE: si vous envoyez un clic par programme à une entrée de fichier afin de l'activer (2), la soumission par programme du formulaire (5) provoquera une erreur de sécurité.

La solution de contournement:

  1. Comme ci-dessus
  2. Tirez parti des fonctionnalités d’accessibilité intégrées à la balise (cliquez sur une étiquette pour activer le contrôle associé) en appelant une balise au lieu d’un lien/bouton.
  3. Écouter l'événement onchange de l'entrée de fichier
  4. Soumettre le formulaire
  5. Pour une raison quelconque, les navigateurs Mozilla n'activeront pas un fichier en cliquant dessus. 
  6. Pour Mozilla, écoutez le clic sur l'étiquette et envoyez un événement de clic à l'entrée du fichier pour l'activer.

J'espère que cela t'aides! Consultez le jsfiddle pour plus de détails sur le html/js/css utilisé pour que tout fonctionne.

11
djibouti33

Le formater comme ceci:

$("#attach").change(function() { 
  alert('I Changed');
});

Mise à jour: Après avoir répondu à une autre question à ce sujet plus tôt, nous avons réalisé que cela avait été corrigé dans le cadre de la réécriture de l'événement jQuery 1.4.2 , il suffit de mettre à jour la dernière version pour résoudre change problème d'événement avec <input type="file" /> dans IE.

10
Nick Craver

J'ai utilisé la solution suivante. J'ai essayé de le rendre aussi autonome que possible.

(function($) {
    if ($.browser.msie == false)
        return;

    $('input[type=file]').live('click', function(e) {
        var self = this;
        var blur = function() {
            $(self).blur();
        }
        setTimeout(blur, 0);
    });

})(jQuery);
3
Venkat D.

C'est probablement un problème de avec une condition de concurrence avec des champs de saisie dans IE. En utilisant setTimeout, la fonction exécutée enregistre alors qu'un changement est survenu. Lorsque le code de l'interface utilisateur est exécuté dans onChangeEvent, cet événement n'a pas encore été déclenché tel qu'il apparaît à IE.

J'ai résolu une situation similaire en procédant comme suit dans mon gestionnaire de modifications:

if (jQuery.browser.msie) { setTimeout(DoSomeUIChange, 0); } else { DoSomeUIChange(); }

DoSomeUIChange est exécuté après le code actuel de la file d'attente des événements et supprime ainsi la situation de concurrence critique.

2
spig

J'avais le même problème avec IE (y compris IE 9). La logique de l'interface utilisateur est la suivante:

  1. cliquer sur un élément div déclenche l'événement click sur un file-input-element de sorte que l'utilisateur clique sur un dialogue div de fichier de déclencheur 
  2. lie le gestionnaire d'événements change au file-input-element pour s'assurer que la form est soumise à la fermeture de la boîte de dialogue d'ouverture de fichier

L'application (s'exécutant à l'intérieur d'un iframe) fonctionne comme un charme sur Chrome et FF. Mais j'ai vite constaté que cela ne fonctionnait pas sous IE, car l'utilisateur a sélectionné un fichier et fermé la boîte de dialogue que le formulaire n'a pas soumise.

La solution finale consiste à supprimer le n ° 1 logique "cliquez sur l'élément div déclencheur click sur l'élément d'entrée de fichier" et laissez l'utilisateur cliquer sur le file input element directement, puis tout fonctionnera.

En passant, la raison pour laquelle nous avons un élément div est que nous voulons masquer les contrôles de rendu du navigateur, car nous avons tout dans l’image d’arrière-plan. Toutefois, si vous définissez display sur none, le contrôle n'est plus en mesure de répondre à un événement d'interaction utilisateur. Nous déplaçons donc le file-input-element hors du port d'affichage et utilisons un élément div pour le remplacer. Comme cela ne fonctionne pas sur IE, nous retournons le file-input-element et fixons-le à opacity. 0. Sur IE 8 ou moins qui ne supporte pas opacity, nous utilisons un filtre pour le rendre transparent: 

#browse {
    filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
    filter: alpha(opacity=0);
    -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
}
2
Gelin Luo

Cela a toujours fonctionné pour moi dans IE6 et IE7.

$('#id-of-input-type-file').change(function(){});
2
Sorpigal

J'ai trouvé cette solutionEn HTML cacher l'élément de fichier (ne pas utiliser display: none, cela ne fonctionnera pas dans IE), préparez l'événement onchange d'IE:

<div style="width: 0px; height: 0px; overflow: hidden;">
  <input id="ifile_template" type="file" onchange="this.focus(); this.blur();"/>
</div>

En javascript pour que la fonction de liaison IE soit floue, et pour FF, la fonction de liaison pour CH change ():

$(iFile).blur(
  function () {
    ...some code...
  }
);

// FF, CH
$(iFile).change(
  function () {
  ...some code...
  }
);
2
d-sauer

Dans IE, l'événement onchange fonctionne correctement lorsqu'il est directement renseigné dans une balise HTML. Comme:

<input type="file" onchange="uploader.upload()" />
1
setty

Ma solution:

setInterval(function()
{
    if ($.browser.msie) $("input[type=file]").blur();
},500);

Pas joli, mais ça marche. ;RÉ

1
Rodrigo Paulino

Regardez ces violons http://jsfiddle.net/uP7A9/531/

HTML:

<input type="file" name="PicturePath" id="fileUpload" accept=".png,.jpg,.jpeg,.gif,.tif" />

jQuery:

$("input[type=file]#fileUpload").on("change", function () {
    alert('hi')
});

cela fonctionne pour tous les navigateurs, testé.

0
Bharat

Je peux confirmer, du moins, que cela ne fonctionne qu'après un événement de flou, similaire à une radio et une case à cocher dans IE. Je vais probablement devoir ajouter un élément visuel pour que l'utilisateur clique dessus et me dise quand il a sélectionné son fichier. 

boiteux.

0
user323774
$("#attach").attr("onChange", "alert('I changed')");

Cela fonctionne dans IE, mais si vous voulez émuler le comportement "live", vous devez ajouter l'attribut "onChange" à chaque nouvel élément lors de la création de son.

0
kapranov.anton

jQuery ne semble pas reconnaître l'événement propertychange. Je l'ai ajouté au nœud DOM à l'aide de la fonction attachEvent() de IE.

var userChoseFile = function($input) {
    // ...
}

var $input = $(/* your file input */);
$input[0].attachEvent('onpropertychange', function() { 
    userChoseFile($input);
});
0
Danyal Aytekin