Estoy usando jQuery para crear botones de opción personalizados y tengo un problema. Al hacer clic en la etiqueta que se asoció con la radio, los eventos de clic se disparan dos veces, si hago clic solo en la radio, está funcionando bien (bueno, en realidad no es la radio en la que estoy haciendo clic, sino el div que envuelve toda la entrada y la etiqueta). Aquí está el código:
El HTML:
<div id="box">
<asp:RadioButtonList ID="RadioButtonList1" runat="server">
<asp:ListItem>RADIO1</asp:ListItem>
<asp:ListItem>RADIO2</asp:ListItem>
<asp:ListItem>RADIO3</asp:ListItem>
</asp:RadioButtonList>
</div>
jQuery:
<script type="text/javascript">
$(function () {
$('#box').find('input:radio').each(function (i) {
var input = $(this);
// get the associated label using the input's id
var label = $('label[for=' + input.attr('id') + ']');
// wrap the input + label in a div
$('<div class="custom-radio"></div>').insertBefore(input).append(label, input);
var wrapperDiv = input.parent();
// find all inputs in this set using the shared name attribute
var allInputs = $('input[name=' + input.attr('name') + ']');
// necessary for browsers that don't support the :hover pseudo class on labels
label.hover(
function () {
$(this).addClass('hover');
}, function () {
$(this).removeClass('hover checkedHover');
});
//bind custom event, trigger it, bind click,focus,blur events
wrapperDiv.bind('updateState', function () {
if ($(this)[0].children[1].checked) {
allInputs.each(function () {
var curDiv = $('div > label[for=' + $(this).attr('id') + ']').parent();
curDiv.removeClass('custom-radio-checked');
curDiv.addClass('custom-radio');
});
$(this).toggleClass('custom-radio custom-radio-checked');
}
else {
$(this).removeClass('custom-radio-checked checkedHover checkedFocus');
}
})
.trigger('updateState')
.click(function () { console.log('click'); })
.focus(function () {
label.addClass('focus');
}).blur(function () {
label.removeClass('focus checkedFocus');
});
});
});
</script>
¿Existe alguna solución para este comportamiento?
jQuery('input').prop('checked', true);
return false;
es equivalente a `evt.stopPropagation (); evt.preventDefault (); ( en jQuery )Intenté agregar la solución anterior agregando:
pero no funcionó. Sin embargo, agregando esto:
¡resuelve el problema! :)
fuente
evt.stopPropagation(); evt.preventDefault();
no lo hizo; 'tVincula el evento de clic a la entrada en lugar de a la etiqueta. Cuando se hace clic en la etiqueta, el evento seguirá ocurriendo porque, como mencionó Dustin, un clic en la etiqueta activa un clic en la entrada. Esto permitirá que la etiqueta mantenga su funcionalidad normal.
En vez de
fuente
change
incluso en el botón de opción, ya que se puede hacer clic en el texto de una etiqueta; no siempre hacen clic en el botón de opción.label > input
configuración Bootstrapesque , esta es LA respuesta, no una respuesta. Agregarevt.stopPropagation()
oevt.preventDefault()
a su código, si bien es efectivo, es un truco que debe evitarse cuando la solución adecuada es mucho más limpia y eficiente.Si está tratando de usar un contenedor externo como un elemento de clic, también puede dejar que los eventos burbujeen naturalmente y probar el elemento esperado en su controlador de clic. Este escenario es útil si está intentando diseñar una zona de clic única para un formulario.
fuente
if (e.target == e.currentTarget) {}
Para solucionar este problema de la manera más sencilla, elimine el atributo "para" de la etiqueta. Un clic en la etiqueta también activará un clic en el elemento asociado. (que en su caso dispara su evento de clic dos veces).
Buena suerte
fuente
Yo suelo usar este Synthax
en vez de
fuente
La mejor respuesta está oculta dentro de los comentarios:
Este violín ilustra que todas las otras soluciones -
stopPropagation
,stopImmediatePropagation
,preventDefault
,return false
- ya sea el cambio nada o destruir la funcionalidad casilla / radio). También ilustra que se trata de un problema básico de JavaScript, no de jQuery.EDITAR: Otra solución de trabajo que acabo de encontrar en otro hilo es vincular
onclick
la entrada en lugar de la etiqueta. Violín actualizado .fuente
Lo he intentado agregando solución.
pero no funcionó.
Añadiendo
¡resuelve el problema! :)
fuente
El problema con e.preventDefault (); es que evita que el clic de la etiqueta marque el botón de opción.
Una mejor solución sería simplemente agregar una verificación rápida "está marcada" como esta:
fuente
Mi problema es un poco diferente, ya
evt.stopPropagation();evt.preventDefault();
que no funciona para mí, solo agregoreturn false;
al final, luego funciona.fuente
En mi caso, el problema era que tenía el evento de clic en una función y la función se ejecutó dos veces ... cada ejecución de la función crea un nuevo evento de clic. - palma de la mano -
después de mover el evento de clic fuera de la función, ¡todo funcionó como se esperaba! :)
fuente
Intente poner su etiqueta de entrada fuera del elemento disparador, porque la etiqueta de etiqueta emula el clic, por lo que siempre tendrá más de una llamada.
fuente
Tuve el mismo problema porque había anidado mi radio dentro de la etiqueta de esta manera con el controlador adjunto a radio_div. La eliminación de la etiqueta anidada solucionó el problema.
fuente
La etiqueta activa la casilla de verificación / radio para marcar.
Impide especialmente que la etiqueta desencadene este comportamiento.
fuente
El clic en la etiqueta con un atributo for = "some-id" activa un nuevo clic, pero solo si el objetivo existe y es una entrada. Estaba no lo pueda resolver perfectamente con e.preventDefault () o cosas por el estilo así que lo hice de esta manera:
Por ejemplo, si tiene esta estructura y desea un evento al hacer clic en .some-class
Lo que funcionó fue:
fuente