2009-08-10 17 views
37

Acabo de notar un comportamiento extraño en IE7.IE - botón de radio oculto no marcado cuando se hace clic en la etiqueta correspondiente

que tienen botones de radio con etiquetas asociadas de la siguiente manera:

<input type="radio" name="filter" id="filter_1" value="Activities" checked="checked" /> 
<label for="filter_1">Activities</label> 

<input type="radio" name="filter" id="filter_2" value="Services" /> 
<label for="filter_2">Services</label> 

El botón de radio se oculta a través de CSS con display: none o visibility: hidden (no preguntar)

El problema es - cuando hago clic en la etiqueta en IE7 (aún no he visto otras versiones de IE), el botón de opción asociado no está realmente marcado. Confirmé esto con jquery: el evento de clic de etiqueta se activó, pero el evento de clic de botón de opción no. Una publicación de formulario también confirma que el botón de opción no cambia.

Esto funciona correctamente en firefox, y también funciona correctamente si elimino el CSS que oculta los botones de opción.

¿Es esto un error de IE o me falta algo?

Respuesta

41

Probablemente tenga que ver con display: none - también puede encontrar que los elementos ocultos no reciben sus valores enviados con el resto del formulario. Si tiene control sobre él, puede intentar positioning the elements off screen rather then hiding them.

+0

+1 Sí, eso funcionará. Tengo más curiosidad si este es un error conocido en IE. – ScottE

+2

No creo que sea un error conocido, sino un comportamiento que no está claramente definido en la especificación. Mirando el artículo de MSDN que está vinculado desde la publicación a la que he vinculado anteriormente, parece que este comportamiento es completamente intencionado por parte de IE. Si se muestra algo: ninguno, entonces efectivamente no es parte del documento. MS ha elegido ignorar estos elementos, Mozilla ha elegido no hacerlo, no es que exista una forma clara o incorrecta de hacerlo. – robertc

+9

No es muy bueno cuando el CSS de un diseñador puede romper los datos que llegan a un manejador de formularios del desarrollador al no transmitir un dato. Este comportamiento huele mal. Gracias por la solución! – Koobz

4

Este problema existe en IE6, 7, 8 e incluso en el actual 9 beta. Como solución, posicionar el botón de radio fuera de pantalla es una buena idea.

Aquí hay una alternativa que no debe involucrar al diseñador o al CSS: Oculte el botón normalmente y haga que cualquier función que maneje el evento click para el botón también maneje el evento click para la etiqueta.

+3

$ ("label"). click (function (e) {e.preventDefault(); $ ("#" + $ (this) .attr ("for")). click(). change();}); – Lane

+0

Lane, esa es una solución genial. Lo estoy agregando como una respuesta para que la gente no lo pase por alto, como casi lo hice :) – bestattendance

1

Reemplazar

style="display:none;" 

con

style="-moz-opacity:0;filter:alpha(opacity:0);opacity:0;" 
3
$("label").click(function(e){ 
    e.preventDefault(); 
    $("#"+$(this).attr("for")).click().change(); 
}); 

Gracias Lane por esto. Lo estoy agregando como respuesta aquí para que la gente no pase por alto tu comentario.

+0

+1 funcionó muy bien, gracias @Lane – brenjt

1

Puede probar esto por IE7,8:

input{ 
    position: absolute; 
    z-index: -1; 
} 

en lugar de

input{ 
    display: none; 
} 
5

Esto funciona para mí

width: 0px; 

Probado en IE7 e IE8. CSS puro no javascript.

1

Hay algunas buenas compilación de sus proposiciones:

input { 
-moz-opacity:0; 
filter:alpha(opacity:0); 
opacity:0; 
position: absolute; 
} 

en lugar de:

display: none; 
19

Ésta es una respuesta wiki para reunir a todas las diferentes respuestas y opciones.

Opción 1: Mover el elemento fuera de la pantalla en lugar de ocultarlo por completo

position: absolute; 
top: -50px; 
left: -50px; 

Opción 2: Use un poco de JavaScript para establecer el botón de radio a una verificación Cuando se hace clic en la etiqueta

$("label").click(function(e){ 
    e.preventDefault(); 
    $("#"+$(this).attr("for")).click().change(); 
}); 

Opción 3: Establecer anchura y/o la opacidad de la elemento a cero

width: 0; 
/* and/or */ 
-moz-opacity:0; 
filter:alpha(opacity:0); 
opacity:0; 
outline:none; /* this prevents IE8 from having the line around it even though it's invisible */ 

Opción 4: Uso otro navegador :)

Básicamente, la especificación de estas cosas no especifica cuál es el comportamiento de usar, pero es decir, generalmente toma la postura de que si no puede ser visto, entonces no funciona. "Visto" y "trabajo" pueden significar cosas diferentes, pero en este caso significa que cuando se establece display:none, la etiqueta no activa el botón de opción, lo que lleva a las soluciones habituales necesarias para tantas cosas en IE.

+0

¡increíble! ¡gracias! –

+0

si lo hace La opción 1 al hacer clic en etiquetas provocará un desplazamiento de página no deseado en FF, IE y Opera porque el navegador intentará enfocar la entrada – Dan

+0

@Dan no está seguro, pero un 'on false' onclick podría corregir ese comportamiento. –

0

Estaba usando la función jQuery hide(), por lo que no fue fácil cambiar la forma en que se oculta un elemento sin escribir un código más complejo. Encontré esta idea: Utilizo class para almacenar el atributo checked y restablecer este atributo de nuevo justo antes del envío.

if ($.browser.msie && $.browser.version == 7.0) { 
$('input[type=radio]').click(function() { 
    $('input[name="'+$(this).attr("name")+'"]').each(function(){ 
     if ($(this).attr("checked")){ 
      $(this).addClass("checked"); 
     }else{ 
      $(this).removeClass("checked"); 
     } 
    }); 
}); 
$('form').submit(function(){ 
    $('input.checked').each(function(){ 
     $(this).attr("checked","true"); 
    }); 
}); 
} 

Funciona como un encanto en mi caso.

Cuestiones relacionadas