Cómo detener el burbujeo de eventos al hacer clic en la casilla de verificación

183

Tengo una casilla de verificación que quiero realizar alguna acción de Ajax en el evento de clic, sin embargo, la casilla de verificación también está dentro de un contenedor con su propio comportamiento de clic que no quiero ejecutar cuando se hace clic en la casilla de verificación. Esta muestra ilustra lo que quiero hacer:

$(document).ready(function() {
  $('#container').addClass('hidden');
  $('#header').click(function() {
    if ($('#container').hasClass('hidden')) {
      $('#container').removeClass('hidden');
    } else {
      $('#container').addClass('hidden');
    }
  });
  $('#header input[type=checkbox]').click(function(event) {
    // Do something
  });
});
#container.hidden #body {
  display: none;
}
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<div id="container">
  <div id="header">
    <h1>Title</h1>
    <input type="checkbox" name="test" />
  </div>
  <div id="body">
    <p>Some content</p>
  </div>
</div>

Sin embargo, no puedo encontrar la manera de detener el burbujeo del evento sin hacer que el comportamiento de clic predeterminado (la casilla de verificación esté marcada / desmarcada) no se ejecute.

Los dos siguientes detienen el burbujeo del evento pero tampoco cambian el estado de la casilla de verificación:

event.preventDefault();
return false;
roryf
fuente
2
Encontré un artículo sobre este asunto que podría ser útil para otros Stack Overflowers. Consejo rápido: haga clic en la fila de la tabla para activar una casilla de verificación Haga clic
Peder Rice

Respuestas:

341

reemplazar

event.preventDefault();
return false;

con

event.stopPropagation();

event.stopPropagation ()

Detiene el burbujeo de un evento a elementos primarios, evitando que cualquier controlador primario sea notificado del evento.

event.preventDefault ()

Impide que el navegador ejecute la acción predeterminada. Use el método isDefaultPrevented para saber si alguna vez se llamó a este método (en ese objeto de evento).

rahul
fuente
44
por alguna razón esto no funciona para mí, pero return false sí.
Randy L
3
Si está vinculando el evento utilizando el .live()método, esto no funcionará. Tendrás que usarlo return false;solo.
rahul
2
Esto funciona usando el .on()método de jQuery (live ahora está en desuso). No pude entender por qué return false no funcionaba.
styfle
Pasé bastante tiempo para descubrir que event.preventDefault () no mostraba la marca de verificación en IE8, pero funcionaba bien en otros navegadores. Encontré esta respuesta después de solucionarlo y luego busqué en google con preventDefault, IE8, casilla de verificación como palabra clave, me trajo aquí.
signonsridhar
no funcionó para ... pero estas dos líneas lo hicieron (sin retorno falso) -> event.preventDefault (); event.stopPropagation ();
Kugan Kumar
32

Use el método stopPropagation:

event.stopPropagation();
Patrice Neff
fuente
29

No olvides IE:

if (event.stopPropagation) {    // standard
        event.stopPropagation();
    } else {    // IE6-8
        event.cancelBubble = true;
}
Faraz Kelhini
fuente
24
Esta respuesta es de 2012. En 2015, olvídate de IE.
Taylan
8
Esto también se aplica a IE9. Mi máquina de prueba IE9 se ahoga en stopPropagation (), pero le gusta cancelBubble (). Y algunas personas / organizaciones todavía usan IE9 en 2016, lamentablemente. Aquellos de nosotros con clientes corporativos no podemos ignorar eso.
Chris Cober
i love ie5 en 2019
SuperUberDuper
5

Como otros han mencionado, intente stopPropagation().

Y hay un segundo controlador para probar: event.cancelBubble = true;es un controlador específico de IE, pero es compatible con al menos FF. Realmente no sé mucho al respecto, ya que no lo he usado yo mismo, pero podría valer la pena, si todo lo demás falla.

peirix
fuente
5

Este es un excelente ejemplo para comprender el concepto de burbujeo de eventos. Según las respuestas anteriores, el código final se verá como se menciona a continuación. Cuando el usuario hace clic en la casilla de verificación, se detendrá la propagación del evento a su elemento principal 'encabezado' event.stopPropagation();.

$(document).ready(function() {
            $('#container').addClass('hidden');
            $('#header').click(function() {
                if($('#container').hasClass('hidden')) {
                    $('#container').removeClass('hidden');
                } else {
                    $('#container').addClass('hidden');
                }
            });
          $('#header input[type=checkbox]').click(function(event) {
              if (event.stopPropagation) {    // standard
                   event.stopPropagation();
               } else {    // IE6-8
                    event.cancelBubble = true;
               }
          });     
  });
mehras
fuente
5

Cuando use jQuery no necesita llamar a una función de detención por separado.

Puedes regresar falseen el controlador de eventos

Esto detendrá el evento y cancelará el burbujeo.

También vea event.preventDefault () vs. return false

De los documentos de jQuery:

Estos manejadores, por lo tanto, pueden evitar que el manejador delegado se active llamando event.stopPropagation()o regresando false.

DutchKevv
fuente
1

Crédito a @mehras por el código. Acabo de crear un fragmento para demostrarlo porque pensé que sería apreciado y quería una excusa para probar esa función.

$(document).ready(function() {
  $('#container').addClass('hidden');
  $('#header').click(function() {
    if ($('#container').hasClass('hidden')) {
      $('#container').removeClass('hidden');
    } else {
      $('#container').addClass('hidden');
    }
  });
  $('#header input[type=checkbox]').click(function(event) {
    if (event.stopPropagation) { // standard
      event.stopPropagation();
    } else { // IE6-8
      event.cancelBubble = true;
    }
  });
});
div {
  text-align: center;
  padding: 2em;
  font-size: 1.2em
}

.hidden {
  display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="header"><input type="checkbox" />Checkbox won't bubble the event, but this text will.</div>
<div id="container">click() bubbled up!</div>

usuario2503764
fuente
Código que realmente muestra cómo usar la variable de evento, gracias.
Moshe Binieli
-1

En angularjs esto debería funcionar:

event.preventDefault(); 
event.stopPropagation();
Kugan Kumar
fuente