Obtenir jQuery pour reconnaître .change () dans IE

131

J'utilise jQuery pour masquer et afficher des éléments lorsqu'un groupe de boutons radio est modifié / cliqué. Cela fonctionne bien dans les navigateurs comme Firefox, mais dans IE 6 et 7, l'action ne se produit que lorsque l'utilisateur clique ensuite ailleurs sur la page.

Pour élaborer, lorsque vous chargez la page, tout semble bien. Dans Firefox, si vous cliquez sur un bouton radio, une ligne du tableau est masquée et l'autre s'affiche immédiatement. Cependant, dans IE 6 et 7, vous cliquez sur le bouton radio et rien ne se passera tant que vous n'aurez pas cliqué quelque part sur la page. Ce n'est qu'alors qu'IE redessine la page, masquant et affichant les éléments pertinents.

Voici le jQuery que j'utilise:

$(document).ready(function () {
  $(".hiddenOnLoad").hide();

  $("#viewByOrg").change(function () {
    $(".visibleOnLoad").show();
    $(".hiddenOnLoad").hide();
  });

  $("#viewByProduct").change(function () {
    $(".visibleOnLoad").hide();
    $(".hiddenOnLoad").show();
  });
});

Voici la partie du XHTML qu'elle affecte. La page entière est validée comme XHTML 1.0 Strict.

<tr>
  <td>View by:</td>
  <td>
    <p>
      <input type="radio" name="viewBy" id="viewByOrg" value="organisation"
      checked="checked" />Organisation</p>
    <p>
      <input type="radio" name="viewBy" id="viewByProduct" value="product" />Product</p>
  </td>
</tr>
<tr class="visibleOnLoad">
  <td>Organisation:</td>
  <td>
    <select name="organisation" id="organisation" multiple="multiple" size="10">
      <option value="1">Option 1</option>
      <option value="2">Option 2</option>
    </select>
  </td>
</tr>
<tr class="hiddenOnLoad">
  <td>Product:</td>
  <td>
    <select name="product" id="product" multiple="multiple" size="10">
      <option value="1">Option 1</option>
      <option value="2">Option 2</option>
    </select>
  </td>
</tr>

Si quelqu'un a des idées pourquoi cela se produit et comment y remédier, ils seraient très appréciés!

Philip Morton
la source

Réponses:

96

Essayez d'utiliser à la .clickplace de .change.

Paolo Bergantino
la source
3
@samjudson, dans mes tests, ce n'est pas correct et le clic de jquery se déclenche lorsque je sélectionne le bouton radio suivant à l'aide des touches fléchées. (vista, ie7)
svandragt
1
@Pacifika: Pas pour moi dans IE7. Au moins, c'est bien. «clic» est un événement totalement différent de «changement» et il y a au moins quelques cas (sinon tous) où c'est un substitut inapproprié.
Bobby Jack le
3
@samjudson: cliquez sur les événements sur les boutons radio et les cases à cocher se déclenchent également lors de leur sélection à l'aide du clavier. Fonctionne dans tous les navigateurs
Philippe Leybaert
4
Je suis corrigé - cela semble être le cas, aussi contre-intuitif que cela puisse être!
Bobby Jack
2
Cela semble être la réponse la plus populaire à cette question particulière, mais ce n'est pas tout à fait correct! clickdiffère de changeen ce que son gestionnaire d'événements sera également appelé en cliquant sur l'option déjà sélectionnée alors que ce changen'est pas le cas. Cette réponse présente un exemple d'utilisation de jQuery .datapour comparer les anciennes et les nouvelles valeurs.
Laoujin le
54

Le problème avec l'utilisation de l' clickévénement au lieu dechange est que vous obtenez l'événement si la même case d'option est sélectionnée (c'est-à-dire n'a pas réellement changé). Cela peut être filtré si vous vérifiez que la nouvelle valeur est différente de l'ancienne. Je trouve cela un peu ennuyeux.

Si vous utilisez l' changeévénement, vous remarquerez peut-être qu'il reconnaîtra le changement après avoir cliqué sur n'importe quel autre élément d'IE. Si vous appelez blur()dans l' clickévénement, cela provoquera le déclenchement de l' changeévénement (uniquement si les boîtes radio ont réellement changé).

Voici comment je fais:

// This is the hack for IE
if ($.browser.msie) {
  $("#viewByOrg").click(function() {
    this.blur();
    this.focus();
  });
}

$("#viewByOrg").change(function() {
  // Do stuff here
});

Vous pouvez maintenant utiliser l'événement de modification comme d'habitude.

Edit: Ajout d'un appel à focus () pour éviter les problèmes d'accessibilité (voir le commentaire de Bobby ci-dessous).

Mark A. Nicolosi
la source
2
C'est un hack très diabolique, car il empêche vos utilisateurs de naviguer à l'aide du clavier, car le focus disparaît après avoir sélectionné un bouton radio.
Philippe Leybaert
5
C'est génial, mais cela pose des problèmes d'accessibilité au clavier. Une fois l'événement blur () déclenché, le bouton radio n'est plus focalisé, donc se déplacer entre les boutons radio avec le clavier devient extrêmement gênant. Ma solution actuelle est d'ajouter un appel à "this.focus ();" immédiatement après l'instruction blur ().
Bobby Jack
1
Je pense que c'est la pire solution présentée, à cause des problèmes d'accessibilité.
Philippe Leybaert
11
Mais le problème d'accessibilité peut être résolu avec un appel à focus (). C'est au moins aussi bon que d'utiliser click () pour tout.
Bobby Jack
Merci Bobby, j'ajouterai cela à la réponse.
Mark A. Nicolosi
33

Avez-vous essayé l'événement onpropertychange d'IE? Je ne sais pas si cela fait une différence, mais cela vaut probablement la peine d'essayer. IE ne déclenche pas l'événement de modification lorsque les valeurs sont mises à jour via le code JS, mais peut-être que onpropertychange fonctionnerait dans cette instance.

$("#viewByOrg").bind($.browser.msie? 'propertychange': 'change', function(e) {
  e.preventDefault(); // Your code here 
}); 
Kevin
la source
"click" ne semble pas fonctionner, mais "propertychange" l'a fait. Merci!
James Kingsbery
J'ai essayé cela dans IE8, cela ne fonctionne pas. Il n'entre pas dans la fonction.
ARUN
14

Cela devrait également fonctionner:

$(document).ready(function(){
   $(".hiddenOnLoad").hide();
   $("#viewByOrg, #viewByProduct").bind(($.browser.msie ? "click" : "change"), function () {
                        $(".visibleOnLoad").show();
                        $(".hiddenOnLoad").hide();
                    });
});

Merci Pier. Cela a été très utile.


la source
C'est, au moins, une bien meilleure réponse que celle actuellement acceptée / la plus votée. Cela ne casse «que» l'accessibilité du clavier sous IE, plutôt que pour tous les bons navigateurs aussi.
Bobby Jack
... bien que ce ne soit pas juste une copie de la réponse de Pier?
Bobby Jack le
D'accord, c'est une version légèrement moins lisible de Pier mais avec les deux sélecteurs liés en un seul appel.
Tristan Warner-Smith le
Remplacez clickpar click keyup keypresspour ajouter la prise en charge du clavier.
aloisdg passe à codidact.com
6

Dans IE, vous devez utiliser l'événement click, dans d'autres navigateurs onchange. Votre fonction pourrait devenir

$(document).ready(function(){
   $(".hiddenOnLoad").hide();
   var evt = $.browser.msie ? "click" : "change";
   $("#viewByOrg").bind(evt, function () {
                        $(".visibleOnLoad").show();
                        $(".hiddenOnLoad").hide();
                    });

   $("#viewByProduct").bind(evt, function () {
                        $(".visibleOnLoad").hide();
                        $(".hiddenOnLoad").show();
                    });     
});
Pier Luigi
la source
Remplacez clickpar click keyup keypresspour ajouter la prise en charge du clavier.
aloisdg passe à codidact.com
6

ajouter ce plugin

jQuery.fn.radioChange = function(newFn){
    this.bind(jQuery.browser.msie? "click" : "change", newFn);
}

puis

$(function(){
    $("radioBtnSelector").radioChange(function(){
        //do stuff
    });
});
dovidweisz
la source
4

J'ai eu le même problème avec le texte d'entrée.

J'ai changé:

$("#myinput").change(function() { "alert('I changed')" });

à

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

et tout fonctionne bien pour moi!

Fabrice
la source
2

C'est un moyen simple de dire à IE de déclencher l'événement de modification lorsque l'utilisateur clique sur l'élément:

if($.browser.msie) {
    $("#viewByOrg").click(function() {
        $(this).change();
    });
}

Vous pouvez étendre cela à quelque chose de plus générique pour travailler avec plus d'éléments de formulaire:

if($.browser.msie) {
    $("input, select").click(function() {
        $(this).change();
    });
    $("input, textarea").keyup(function() {
        $(this).change();
    });
}
Paul
la source
1

Je suis presque sûr que c'est un problème connu avec IE. L'ajout d'un gestionnaire pour l' onclickévénement devrait résoudre le problème:

$(document).ready(function(){

    $(".hiddenOnLoad").hide();

    $("#viewByOrg").change(function () {
        $(".visibleOnLoad").show();
        $(".hiddenOnLoad").hide();
    });

    $("#viewByOrg").click(function () {
        $(".visibleOnLoad").show();
        $(".hiddenOnLoad").hide();
    });

    $("#viewByProduct").change(function () {
        $(".visibleOnLoad").hide();
        $(".hiddenOnLoad").show();
    });     

    $("#viewByProduct").click(function () {
        $(".visibleOnLoad").hide();
        $(".hiddenOnLoad").show();
    });     
});
Chris Zwiryk
la source
1

Dans IE, forcez la radio et les cases à cocher à déclencher un événement «changement»:

if($.browser.msie && $.browser.version < 8)
  $('input[type=radio],[type=checkbox]').live('click', function(){
    $(this).trigger('change');
  });
Jeoff Wilks
la source
1

à partir de jquery 1.6, ce n'est plus un problème ... je ne sais pas quand il a été corrigé ... Merci mon Dieu pour cela.

Baz1nga
la source
1

Si vous changez votre version de jQuery en 1.5.1, vous n'aurez pas à ajuster votre code. Ensuite, IE9 écoutera parfaitement:

$(SELECTOR).change(function() {
    // Shizzle
});

http://code.jquery.com/jquery-1.5.1.min.js

Bas Matthee
la source
1

l'astuce avec le clic fonctionne ... mais si vous voulez obtenir le bon état de la radio ou de la case à cocher, vous pouvez utiliser ceci:

(function($) {
    $('input[type=checkbox], input[type=radio]').live('click', function() {
       var $this = $(this);
       setTimeout(function() {
          $this.trigger('changeIE'); 
       }, 10) 
    });
})(jQuery);

$(selector).bind($.browser.msie && $.browser.version <= 8 ? 'changeIE' : 'change', function() {
  // do whatever you want
})
pas d'arrêt
la source
0

imo en utilisant le clic au lieu du changement rend le comportement ie différent. Je préfère émuler le comportement de l'événement de changement à l'aide d'une minuterie (setTimout).

quelque chose comme (avertissement - code du bloc-notes):

if ($.browser.msie) {
  var interval = 50;
  var changeHack = 'change-hac';
  var select = $("#viewByOrg");
  select.data(changeHack) = select.val();
  var checkVal=function() {
    var oldVal = select.data(changeHack);
    var newVal = select.val();
    if (oldVal !== newVal) {
      select.data(changeHack, newVal);
      select.trigger('change')
    }
    setTimeout(changeHack, interval);
  }
  setTimeout(changeHack, interval);
}

$("#viewByOrg").change(function() {
  // Do stuff here
});
Ken Egozi
la source
whoah ... un peu lourd, non?
orip
0

essaie ça, ça marche pour moi

$("#viewByOrg")
        .attr('onChange', $.browser.msie ? "$(this).data('onChange').apply(this)" : "")
        .change( function(){if(!$.browser.msie)$(this).data('onChange').apply(this)} )
        .data('onChange',function(){alert('put your codes here')});
RainChen
la source
0

Cela peut aider quelqu'un: au lieu de commencer par l'ID du formulaire, ciblez l'ID de sélection et soumettez le formulaire en cas de modification, comme ceci:

<form id='filterIt' action='' method='post'>
  <select id='val' name='val'>
    <option value='1'>One</option>
    <option value='2'>Two</option>
    <option value='6'>Six</option>
  </select>
  <input type="submit" value="go" />
</form>

et le jQuery:

$('#val').change(function(){
  $('#filterIt').submit();
});

(Évidemment, le bouton d'envoi est facultatif, au cas où javascript serait désactivé)

Jongosi
la source
0

Essayez ce qui suit:

.bind($.browser.msie ? 'click' : 'change', function(event) {
Bilal Jalil
la source
0

Évitez d'utiliser .focus () ou .select () avant la fonction .change () de jquery pour IE, alors cela fonctionne bien, je l'utilise dans mon site.

Merci

muhammadanish
la source
0
//global
var prev_value = ""; 

$(document).ready(function () {

 if (jQuery.browser.msie && $.browser.version < 8)
      $('input:not(:submit):not(:button):not(:hidden), select, textarea').bind("focus", function () { 
         prev_value = $(this).val();

       }).bind("blur", function () { 
         if($(this).val() != prev_value)
         has_changes = true;
       });
}
Kiev
la source
0

Veuillez essayer d'utiliser chacun au lieu de modifier / cliquer , ce qui fonctionne bien même la première fois dans IE ainsi que dans d'autres navigateurs

Ne fonctionne pas une première fois

$("#checkboxid").**change**(function () {

});

Fonctionne bien même la première fois

$("#checkboxid").**each**(function () {

});
Dayanand Rupanavar
la source