Como parar o evento borbulhante ao clicar na caixa de seleção

183

Eu tenho uma caixa de seleção que desejo executar alguma ação do Ajax no evento click, no entanto, a caixa de seleção também está dentro de um contêiner com seu próprio comportamento de clique que não quero executar quando a caixa de seleção é clicada. Este exemplo ilustra o que eu quero fazer:

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

No entanto, não consigo descobrir como parar o evento de bolhas sem causar o comportamento padrão do clique (a caixa de seleção sendo marcada / desmarcada) não seja executada.

Os itens a seguir interrompem a interferência do evento, mas também não alteram o estado da caixa de seleção:

event.preventDefault();
return false;
roryf
fonte
2
Encontrei um artigo sobre esse assunto que pode ser útil para outros Stack Overflowers. Dica rápida: Clique na linha da tabela para acionar uma caixa de seleção Clique
Peder Rice

Respostas:

341

substituir

event.preventDefault();
return false;

com

event.stopPropagation();

event.stopPropagation ()

Interrompe a interferência de um evento nos elementos pai, impedindo que qualquer manipulador pai seja notificado sobre o evento.

event.preventDefault ()

Impede que o navegador execute a ação padrão. Use o método isDefaultPrevented para saber se esse método já foi chamado (nesse objeto de evento).

rahul
fonte
4
por alguma razão, isso não funciona para mim, mas o retorno falso funcionou.
Randy L
3
Se você estiver vinculando o evento usando o .live()método, isso não funcionará. Você terá que se usar return false;.
rahul
2
Isso funciona usando o .on()método jQuery (live agora está obsoleto). Não consegui descobrir por que o retorno falso não estava funcionando.
Styfle 17/02
Passei um bom tempo descobrindo que event.preventDefault () não estava mostrando a marca de seleção no IE8, mas funcionou bem em outros navegadores. Encontrei esta resposta depois de corrigir e, em seguida, pesquisar no preventDefault, IE8, caixa de seleção como palavra-chave, me trouxe aqui.
signonsridhar
não funcionou para .. mas essas duas linhas funcionaram (sem retorno false) -> event.preventDefault (); event.stopPropagation ();
Kugan Kumar #
32

Use o método stopPropagation:

event.stopPropagation();
Patrice Neff
fonte
29

Não se esqueça do IE:

if (event.stopPropagation) {    // standard
        event.stopPropagation();
    } else {    // IE6-8
        event.cancelBubble = true;
}
Faraz Kelhini
fonte
24
Esta resposta é de 2012. Em 2015, por favor, esqueça o IE.
Taylan
8
Isso se aplica ao IE9 também. Minha máquina de teste do IE9 engasga com stopPropagation (), mas gosta de cancelBubble (). E algumas pessoas / organizações ainda estão usando o IE9 em 2016, infelizmente. Aqueles de nós com clientes corporativos não podem ignorar isso.
Chris Cober
Eu amo ie5 em 2019
SuperUberDuper
5

Como outros já mencionaram, tente stopPropagation().

E há um segundo manipulador para tentar: event.cancelBubble = true;É um manipulador específico do IE, mas é suportado em pelo menos FF. Realmente não sei muito sobre isso, pois eu não o usei, mas pode valer a pena tentar, se tudo mais falhar.

peirix
fonte
5

Este é um excelente exemplo para entender o conceito de bolhas de eventos. Com base nas respostas acima, o código final será semelhante ao mencionado abaixo. Onde o usuário clica na caixa de seleção, a propagação do evento para o elemento pai 'header' será interrompida 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
fonte
5

Ao usar o jQuery, você não precisa chamar uma função de parada separadamente.

Você pode simplesmente retornar falseno manipulador de eventos

Isso interromperá o evento e cancelará a interferência.

Veja também event.preventDefault () vs. return false

Nos documentos do jQuery:

Esses manipuladores, portanto, podem impedir que o manipulador delegado seja acionado chamando event.stopPropagation()ou retornando false.

DutchKevv
fonte
1

Crédito para @mehras pelo código. Acabei de criar um snippet para demonstrá-lo, porque pensei que seria apreciado e queria uma desculpa para experimentar esse recurso.

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

user2503764
fonte
Código que realmente mostra como usar a variável de evento, obrigado.
Moshe Binieli 31/10
-1

No angularjs, isso deve funcionar:

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