131 votes

Faire en sorte que jQuery reconnaisse .change() dans IE

J'utilise jQuery pour masquer et afficher des éléments lorsqu'un groupe de boutons radio est modifié/cliqué. Cela fonctionne bien dans des 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 correct. Dans Firefox, si vous cliquez sur un bouton radio, une ligne du tableau est masquée et l'autre s'affiche immédiatement. Toutefois, dans IE 6 et 7, vous cliquez sur le bouton radio et rien ne se passe jusqu'à ce que vous cliquiez quelque part dans la page. Ce n'est qu'à ce moment-là qu'IE redessine la page, en masquant et en affichant les éléments concernés.

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'il 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 une idée de la raison pour laquelle cela se produit et de la manière de le réparer, il serait très apprécié !

96voto

Paolo Bergantino Points 199336

Essayez d'utiliser .click au lieu de .change .

54voto

Mark A. Nicolosi Points 11859

Le problème de l'utilisation du click au lieu de change c'est que vous obtenez l'événement si la même case d'option est sélectionnée (c'est-à-dire qu'elle 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 le change vous remarquerez peut-être qu'il reconnaîtra le changement après que vous aurez cliqué sur n'importe quel autre élément dans IE. Si vous appelez blur() en el click il provoquera l'événement change (uniquement si les cases d'option ont été modifiées).

Voici comment je m'y prends :

// 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 changement comme d'habitude.

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

33voto

Kevin Points 301

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 changement lorsque les valeurs sont mises à jour via le code JS, mais peut-être que onpropertychange fonctionnerait dans ce cas.

$("#viewByOrg").bind($.browser.msie? 'propertychange': 'change', function(e) {
  e.preventDefault(); // Your code here 
});

14voto

Cela devrait aussi fonctionner :

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

Merci Pier. C'était très utile.

6voto

Pier Luigi Points 4428

Dans IE, vous devez utiliser l'événement click, dans les 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();
                    });     
});

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