web-dev-qa-db-fra.com

Obtenir 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 les navigateurs tels que 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 va bien. Dans Firefox, si vous cliquez sur un bouton radio, une ligne du tableau est masquée et l’autre est affichée 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. Ensuite, IE redessine la page en masquant et en 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 concernée. La page entière est validée en tant que 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 comment y remédier, il serait très apprécié!

131
Philip Morton

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

96
Paolo Bergantino

Le problème avec l'utilisation de l'événement click au lieu de change 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 agaçant.

Si vous utilisez l'événement change, vous remarquerez qu'il reconnaîtra la modification après avoir cliqué sur un autre élément d'IE. Si vous appelez blur() dans l'événement click, l'événement change sera déclenché (uniquement si les cases d'option ont été modifiées).

Voici comment je le 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 change comme d'habitude.

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

54
Mark A. Nicolosi

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 change lorsque les valeurs sont mises à jour via le code JS mais onpropertychange pourrait fonctionner dans ce cas.

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

Cela devrait fonctionner aussi:

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

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

14
Arthur Bezner

ajouter ce plugin

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

puis 

$(function(){
    $("radioBtnSelector").radioChange(function(){
        //do stuff
    });
});
6
dovidweisz

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();
                    });     
});
6
Pier Luigi

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!

4
fabrice

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

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

Vous pouvez développer ceci en quelque chose de plus générique pour utiliser plus d'éléments de formulaire:

if($.browser.msie) {
    $("input, select").click(function() {
        $(this).change();
    });
    $("input, textarea").keyup(function() {
        $(this).change();
    });
}
2
paul

Dans IE, forcez la radio et les cases à cocher pour déclencher un événement "change":

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

Je suis à peu près sûr que c'est un problème connu avec IE. L'ajout d'un gestionnaire pour l'événement onclick 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();
    });     
});
1
Chris Zwiryk

Si vous modifiez votre version de jQuery à la version 1.5.1, vous n’aurez pas à ajuster votre code. Ensuite, IE9 sera parfait pour:

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

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

1
Bas Matthee

depuis jquery 1.6, ce n’est plus un problème .. je ne sais pas quand cela a été corrigé .. dieu merci

1
Baz1nga

le truc avec le clic fonctionne ... mais si vous voulez obtenir le bon état de la radio ou une 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
})
1
nostop

Évitez d’utiliser .focus () ou .select () before .change () function of jquery pour IE, alors cela fonctionne bien, je l’utilise dans mon site.

Merci

0
Danish

essayez ç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')});
0
RainChen

imo utiliser click au lieu de changer rend le comportement ie différent de celui-ci .. Je préférerais émuler le comportement de l'événement change à l'aide d'un timer (setTimout).

quelque chose comme (avertissement - code 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
});
0
Ken Egozi

Essayez ce qui suit:

.bind($.browser.msie ? 'click' : 'change', function(event) {
0
Bilal Jalil
//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;
       });
}
0
kiev

Veuillez essayer avec each au lieu de change / click , 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 () {

});
0

Cela peut aider une personne: 

<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, si javascript est désactivé)

0
Jongosi