2008-10-16 8 views
129

Estoy usando jQuery para ocultar y mostrar elementos cuando se altera/se hace clic en un grupo de botones de opción. Funciona bien en navegadores como Firefox, pero en IE 6 y 7, la acción solo ocurre cuando el usuario hace clic en algún otro lugar de la página.Cómo obtener jQuery para reconocer .change() en IE

Para elaborar, cuando carga la página, todo se ve bien. En Firefox, si hace clic en un botón de opción, una fila de la tabla se oculta y la otra se muestra inmediatamente. Sin embargo, en IE 6 y 7, haga clic en el botón de opción y no pasará nada hasta que haga clic en algún lugar de la página. Solo entonces IE vuelve a dibujar la página, ocultándose y mostrando los elementos relevantes.

Aquí está el jQuery que estoy usando:

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

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

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

Aquí es la parte de la XHTML que afecta. Toda la página valida como 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 alguien tiene alguna idea por qué ocurre esto y cómo solucionarlo, que sería muy apreciado!

Respuesta

96

Intente utilizar .click en lugar de .change.

+0

Gracias, funcionó a la perfección. –

+0

El evento Click solo funciona si cambia el valor con el mouse; si usa el teclado, el clic no se activa, pero el cambio sí. – samjudson

+3

@samjudson, en mi prueba esto no es correcto y el clic de jquery se dispara cuando selecciono el siguiente botón de opción con las teclas de flecha. (vista, ie7) – svandragt

1

Estoy bastante seguro de que este es un problema conocido con IE. Adición de un controlador para el evento onclick debería solucionar el 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(); 
    });  
}); 
6

En IE debe utilizar el evento click, en otros navegadores onchange. Su función podría convertirse

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

Reemplazar 'click' con' click keyup keypress' para agregar soporte de teclado. – aloisdg

14

Esto debería funcionar también:

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

Gracias Pier. Esto fue muy útil.

+0

Esta es, al menos, una respuesta mucho mejor que la actual aceptada/más votada. Solo 'rompe' la accesibilidad del teclado bajo IE, en lugar de para todos los buenos navegadores también. –

+0

... aunque, ¿no es esto solo una copia de la respuesta de Pier? –

+0

De acuerdo, es una versión ligeramente menos legible de la de Pier, pero con ambos selectores vinculados en una sola llamada. –

54

El problema con el uso del evento click en lugar de change es que obtiene el evento si se selecciona la misma casilla de radio (es decir, no ha cambiado realmente). Esto puede filtrarse si comprueba que el nuevo valor sea diferente al anterior. Encuentro esto un poco molesto.

Si utiliza el evento change, puede observar que reconocerá el cambio después de hacer clic en cualquier otro elemento en IE. Si llama al blur() en el evento click, provocará que el evento change se dispare (solo si las cajas de radio realmente han cambiado).

Así es como lo estoy haciendo:

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

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

Ahora puede utilizar el evento de cambio como normal.

Editar: Se agregó una llamada a focus() para evitar problemas de accesibilidad (consulte el comentario de Bobby a continuación).

+2

Es un hack muy malvado, ya que evita que los usuarios naveguen con el teclado, ya que el foco desaparece después de seleccionar un botón de opción. –

+5

Esto es genial, pero causa problemas de accesibilidad del teclado.Una vez que se ha disparado el evento blur(), el botón de radio ya no se enfoca, por lo que moverse entre los botones de radio con el teclado se vuelve extremadamente incómodo. Mi solución actual es agregar una llamada a "this.focus();" inmediatamente después de la declaración blur(). –

+0

¿Por qué los votos a favor? Esta es (casi) la mejor solución aquí. –

0

imo usando click en lugar de change hace que el comportamiento ie sea diferente. Prefiero emular el comportamiento del evento de cambio usando un temporizador (setTimout).

algo así como (advertencia - código de bloc de notas):

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

whoah ... un poco torpe, ¿no? – orip

33

¿Usted ha intentado caso onPropertyChange de IE? No sé si hace una diferencia, pero probablemente valga la pena intentarlo. IE no activa el evento de cambio cuando los valores se actualizan a través del código JS, pero quizás onpropertychange funcionaría en esta instancia.

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

"clic" no parecía funcionar, pero "propertychange" sí. ¡Gracias! –

+0

Probé esto en IE8 no está funcionando. No está llegando dentro de la función. – ARUN

4

Tuve el mismo problema con el texto de entrada.

me cambió:

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

a

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

y todo está funcionando bien para mí!

+0

¡lo único que funciona hasta ahora! Gran hallazgo – NothinRandom

2

Esta es una forma sencilla de decir IE para disparar el evento de cambio cuando se hace clic en el elemento:

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

Usted puede ampliar esto a algo más genérico para trabajar con más elementos de formulario:

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

¡Es trabajos !!!!! – Marztres

0

probar esto, a mí me funciona

$("#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')}); 
6

añadir este plugin

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

continuación

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

En IE, radio vigor y casillas de verificación para activar un "cambio" evento:

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

Esto puede ayudar a alguien: En lugar de comenzar con el ID del formulario, Diríjase a la ID de selección y envíe el formulario al cambiar, como este:

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

y el jQuery:

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

(Obviamente, el botón de envío es opcional, en caso de javascript está deshabilitado)

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

como de jQuery 1.6 esto ya no es un problema .. no estoy seguro cuando sin embargo, se arregló ... Gracias a Dios, aunque

1

Si cambias tu versión de jQuery a la 1.5.1, no tendrás que ajustar tu código. Entonces IE9 Wil escuchar simplemente perfecto a:

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

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

1

el truco funciona con el clic ...pero si usted desea conseguir el correcto estado de la radio o la Casilla de selección se puede utilizar este:

(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

intente lo siguiente:

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

Evitar el uso de .focus() o .select() antes de .change() función de jquery para IE, entonces funciona bien, estoy usándolo en mi sitio.

Gracias

0

Por favor, intente con el uso de cada en lugar de cambio/clic, que está trabajando bien, incluso primera vez en el IE, así como otros navegadores

no funciona una primera vez

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

}); 

Trabajo bien incluso la primera vez

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

});