Far riconoscere a jQuery .change () in IE


131

Sto usando jQuery per nascondere e mostrare elementi quando un gruppo di pulsanti di opzione viene modificato / cliccato. Funziona bene in browser come Firefox, ma in IE 6 e 7, l'azione si verifica solo quando l'utente fa clic da qualche altra parte nella pagina.

Per elaborare, quando carichi la pagina, tutto sembra a posto. In Firefox, se fai clic su un pulsante di opzione, una riga della tabella viene nascosta e l'altra viene visualizzata immediatamente. Tuttavia, in IE 6 e 7, fai clic sul pulsante di opzione e non accadrà nulla finché non fai clic in qualche punto della pagina. Solo allora IE ridisegna la pagina, nascondendo e mostrando gli elementi rilevanti.

Ecco il jQuery che sto usando:

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

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

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

Ecco la parte dell'XHTML che colpisce. L'intera pagina viene convalidata come 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>

Se qualcuno ha qualche idea sul perché questo accada e su come risolverlo, sarebbe molto apprezzato!

Risposte:


96

Prova a usare .clickinvece di .change.


3
@samjudson, nei miei test questo non è corretto e il clic di jquery si innesca quando seleziono il pulsante di opzione successivo usando i tasti freccia. (vista, ie7)
svandragt

1
@Pacifika: non per me in IE7. Almeno ha ragione. "click" è un evento totalmente diverso da "change" e ci sono almeno alcuni casi (se non tutti) in cui è un sostituto inappropriato.
Bobby Jack,

3
@samjudson: fai clic sugli eventi sui pulsanti di opzione e le caselle di controllo vengono attivate anche quando li selezioni utilizzando la tastiera. Funziona in tutti i browser
Philippe Leybaert,

4
Sono corretto - questo sembra essere il caso, per quanto contro-intuitivo possa essere!
Bobby Jack,

2
Questa sembra essere la risposta più popolare a questa particolare domanda ma non è del tutto corretta! clickdifferisce dal fatto changeche il suo gestore eventi verrà chiamato anche quando si fa clic sull'opzione già selezionata, mentre changenon lo è. Questa risposta ha un esempio di come utilizzare jQuery .dataper confrontare i valori vecchi e nuovi.
Laoujin,

54

Il problema con l'utilizzo clickdell'evento invece di changeè che si ottiene l'evento se è selezionata la stessa radio box (cioè non è stata effettivamente modificata). Questo può essere filtrato se si controlla che il nuovo valore è diverso dal vecchio. Lo trovo un po 'fastidioso.

Se si utilizza l' changeevento, è possibile notare che riconoscerà la modifica dopo aver fatto clic su qualsiasi altro elemento in IE. Se si chiama blur()l' clickevento, si verificherà un changeevento (solo se le radio box sono effettivamente cambiate).

Ecco come lo sto facendo:

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

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

Ora puoi utilizzare l'evento change come al solito.

Modifica: aggiunta una chiamata a focus () per prevenire problemi di accessibilità (vedi il commento di Bobby di seguito).


2
È un trucco molto malvagio, perché impedisce agli utenti di navigare utilizzando la tastiera, perché lo stato attivo scompare dopo aver selezionato un pulsante di opzione.
Philippe Leybaert,

5
Questo è fantastico, ma causa problemi di accessibilità da tastiera. Una volta che l'evento sfocatura () è stato attivato, il pulsante di opzione non è più focalizzato, quindi spostarsi tra i pulsanti di opzione con la tastiera diventa estremamente imbarazzante. La mia soluzione attuale è quella di aggiungere una chiamata a "this.focus ();" immediatamente dopo l'istruzione blur ().
Bobby Jack,

1
Penso che sia la peggiore soluzione presentata, a causa dei problemi di accessibilità.
Philippe Leybaert,

11
Ma il problema dell'accessibilità può essere risolto con una chiamata a focus (). È almeno buono come usare click () per tutto.
Bobby Jack,

Grazie Bobby, lo aggiungerò alla risposta.
Mark A. Nicolosi,

33

Hai provato l'evento onpropertychange di IE? Non so se fa la differenza, ma probabilmente vale la pena provare. IE non attiva l'evento change quando i valori vengono aggiornati tramite il codice JS ma forse onpropertychange funzionerebbe in questa istanza.

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

"click" non sembra funzionare, ma "scambio di proprietà" ha funzionato. Grazie!
James Kingsbery,

Ho provato questo in IE8 non funziona. Non viene all'interno della funzione.
ARUN,

14

Anche questo dovrebbe funzionare:

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

Grazie Pier. Questo è stato molto utile.


Questa è, almeno, una risposta molto migliore di quella attualmente accettata / votata più alta. "Solo" rompe l'accessibilità della tastiera in IE, piuttosto che per tutti i buoni browser.
Bobby Jack,

... anche se non è solo una copia della risposta di Pier?
Bobby Jack,

D'accordo, è una versione leggermente meno leggibile di Pier ma con entrambi i selettori associati in una sola chiamata.
Tristan Warner-Smith,

Sostituisci clickcon click keyup keypressper aggiungere il supporto tastiera.
aloisdg si trasferisce su codidact.com il

6

In IE è necessario utilizzare l'evento click, in altri browser onchange. La tua funzione potrebbe diventare

$(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();
                    });     
});

Sostituisci clickcon click keyup keypressper aggiungere il supporto tastiera.
aloisdg si trasferisce su codidact.com il

6

aggiungi questo plugin

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

poi

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

4

Ho avuto lo stesso problema con il testo di input.

Ho cambiato:

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

per

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

e tutto funziona bene per me!


2

Questo è un modo semplice per dire a IE di attivare l'evento change quando si fa clic sull'elemento:

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

Puoi espanderlo in qualcosa di più generico per lavorare con più elementi del modulo:

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

1

Sono abbastanza sicuro che questo sia un problema noto con IE. L'aggiunta di un gestore per l' onclickevento dovrebbe risolvere il problema:

$(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

In IE, imponi alla radio e alle caselle di controllo di attivare un evento "modifica":

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

1

a partire da jquery 1.6 questo non è più un problema .. non sono sicuro di quando sia stato risolto però .. Grazie a dio per questo però



1

il trucco con il clic funziona ... ma se vuoi ottenere lo stato radio o la casella di controllo corretti puoi usare questo:

(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
})

0

imo usando click invece di change rende il comportamento ie diverso. Preferirei emulare il comportamento dell'evento change usando un timer (setTimout).

qualcosa come (avviso - codice blocco note):

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
});

whoah ... un po 'pesante, no?
Orip,

0

prova questo, funziona per me

$("#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

Questo può aiutare qualcuno: invece di iniziare con l'id del modulo, scegli come target l'id selezionato e invia il modulo in caso di modifica, in questo modo:

<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>

e il jQuery:

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

(Ovviamente, il pulsante di invio è facoltativo, nel caso in cui JavaScript sia disabilitato)


0

Prova quanto segue:

.bind($.browser.msie ? 'click' : 'change', function(event) {

0

Evita di usare .focus () o .select () prima della funzione .change () di jquery per IE, quindi funziona benissimo, lo sto usando nel mio sito.

Grazie


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;
       });
}

0

Prova a utilizzare ciascuno invece di modifica / clic , che funziona bene anche la prima volta in IE e in altri browser

Non funziona la prima volta

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

});

Funziona bene anche la prima volta

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

});
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.