Como parar a propagação de eventos com o atributo embutido onclick?


313

Considere o seguinte:

<div onclick="alert('you clicked the header')" class="header">
  <span onclick="alert('you clicked inside the header');">something inside the header</span>
</div>

Como posso fazer para que, quando o usuário clicar no intervalo, ele não dispara o divevento de clique?

Respostas:


272

Use event.stopPropagation () .

<span onclick="event.stopPropagation(); alert('you clicked inside the header');">something inside the header</span>

Para o IE: window.event.cancelBubble = true

<span onclick="window.event.cancelBubble = true; alert('you clicked inside the header');">something inside the header</span>

11
Não existe o objeto de evento no FireFox.
— Robert C. Barth

6
O objeto de evento é um parâmetro do retorno de chamada. Na verdade, não existe tal coisa como o objeto de evento no IE, porque esse objeto é acessível através window.event vez de ser um parâmetro da função :-)
— Vincent Robert

66
Isso está errado - os manipuladores onclick inline não passam o evento como argumento. A solução correta é Gareths, abaixo.
— Benubird

2
No Firefox, você pode ter acesso a um evento variável no script embutido, mas o window.event não está disponível. <div onclick = "alert (event);"> </div>
— Morgan Cheng

1
eventparece estar disponível também em eventos embutidos no IOS Safari.
— Yuval A.

210

Existem duas maneiras de obter o objeto de evento de dentro de uma função:

  1. O primeiro argumento, em um navegador compatível com W3C (Chrome, Firefox, Safari, IE9 +)
  2. O objeto window.event no Internet Explorer (<= 8)

Se você precisar dar suporte a navegadores herdados que não seguem as recomendações do W3C, geralmente dentro de uma função você usaria algo como o seguinte:

function(e) {
  var event = e || window.event;
  [...];
}

que verificaria primeiro um e depois o outro e armazenaria o que fosse encontrado na variável de evento. No entanto, em um manipulador de eventos embutido, não há um eobjeto a ser usado. Nesse caso, você deve tirar proveito da argumentscoleção que está sempre disponível e se refere ao conjunto completo de argumentos passados ​​para uma função:

onclick="var event = arguments[0] || window.event; [...]"

No entanto, de um modo geral, você deve evitar manipuladores de eventos em linha se precisar de algo complicado, como interromper a propagação. Escrever seus manipuladores de eventos separadamente e anexá-los a elementos é uma idéia muito melhor a médio e longo prazo, tanto para facilitar a leitura quanto a manter a manutenção.


11
De um ouvinte em linha, você pode passar o objeto evento como: onclick="foo(event)", em seguida, na função function foo(event){/* do stuff with event */}. Isso funciona nos modelos de eventos IE e W3C.
— RobG

5
Que "menor ou igual a oito" é um tanto ... ambíguo.
— TechNyquist

8
isso realmente não responde à pergunta.
— jcomeau_ictx

1
resposta pura a uma pergunta diferente. : - /
— Arel 28/10

80

Lembre-se de que o window.event não é suportado no FireFox e, portanto, deve ser algo parecido com:

e.cancelBubble = true

Ou você pode usar o padrão W3C para FireFox:

e.stopPropagation();

Se você quiser ser chique, faça o seguinte:

function myEventHandler(e)
{
    if (!e)
      e = window.event;

    //IE9 & Other Browsers
    if (e.stopPropagation) {
      e.stopPropagation();
    }
    //IE8 and Lower
    else {
      e.cancelBubble = true;
    }
}

12
E para fazê-lo funcionar, é preciso chamar isso assim:<div onclick="myEventHandler(event);">
— DarkDust

1
Pode ser "evento || window.event".
— Pointy

1
if (e.cancelBubble) não parece certo para mim, você defini-lo como true se ele já é verdade
— Guillaume86

e.cancelBubbleretorna falso no IE! Não pode alcançar a e.cancelBubble = true;instrução. Em vez disso, use a condição do SoftwareARM !!
— mauretto

45

Use esta função, ele testará a existência do método correto.

function disabledEventPropagation(event)
{
   if (event.stopPropagation){
       event.stopPropagation();
   }
   else if(window.event){
      window.event.cancelBubble=true;
   }
}

20

Eu tive o mesmo problema - caixa de erro js no IE - isso funciona bem em todos os navegadores, tanto quanto eu posso ver (event.cancelBubble = true faz o trabalho no IE)

onClick="if(event.stopPropagation){event.stopPropagation();}event.cancelBubble=true;"

1
Obrigado @MSC exatamente o que eu precisava!
— DannyC

1
Script embutido. Ele faz responder à pergunta
— Cesar

10

Isso funcionou para mim

<script>
function cancelBubble(e) {
 var evt = e ? e:window.event;
 if (evt.stopPropagation)    evt.stopPropagation();
 if (evt.cancelBubble!=null) evt.cancelBubble = true;
}
</script>

<div onclick="alert('Click!')">
  <div onclick="cancelBubble(event)">Something inside the other div</div>
</div>

Tem certeza de que esse snippet de código exato funcionou para você? Porque parece que há um problema de citação de string no manipulador onclick da div externa ...?!
— Nicole Nicole

7

Para páginas da Web do ASP.NET (não MVC), você pode usar o Sys.UI.DomEventobjeto como invólucro do evento nativo.

<div onclick="event.stopPropagation();" ...

ou, passe o evento como um parâmetro para a função interna:

<div onclick="someFunction(event);" ...

e em alguma função:

function someFunction(event){
    event.stopPropagation(); // here Sys.UI.DomEvent.stopPropagation() method is used
    // other onclick logic
}


2

Como não posso comentar por causa do Karma, escrevo a resposta como um todo: De acordo com a resposta de Gareth (var e = argumentos [0] || window.event; [...]) usei esse oneliner on-line no onclick para um hack rápido:

<div onclick="(arguments[0] || window.event).stopPropagation();">..</div>

Sei que é tarde, mas queria que você soubesse que isso funciona em uma linha. Os chavetas retornam um evento que tem a função stopPropagation anexada nos dois casos, então tentei encapsulá-los entre chavetas, como no if e .... funciona. :)


1

Isso também funciona - No link HTML, use onclick com retorno como este:

<a href="mypage.html" onclick="return confirmClick();">Delete</a>

E então a função comfirmClick () deve ser como:

function confirmClick() {
    if(confirm("Do you really want to delete this task?")) {
        return true;
    } else {
        return false;
    }
};

2
Não é isso que a pergunta significa.
— jzonthemtn

jbird @ Isso é exatamente o que a pergunta significava. É uma maneira (mais antiga) diferente de cancelar um evento de borbulhar na árvore dom (está nas especificações do nível 1 da API do dom).
— G1_13

@ gion_13 Mas a ação do clique não é algo que o usuário precisa confirmar. Na pergunta, queremos apenas que o onclick da criança () seja acionado e não o onclick do pai (). Colocar um prompt do usuário entre eles não é útil. Espero que você possa ver essa diferença.
— precisa saber é o seguinte

1
O confirmnão é relevante. Estou me referindo ao valor de retorno . citação: No link HTML, use onclick com retorno como este
— gion_13

retornando falsos cancela seguindo o link, ele não cancelar a propagação no meu cromo
— commonpike

1

Por que não apenas verificar qual elemento foi clicado? Se você clicar em algo, window.event.targetserá atribuído ao elemento que foi clicado e o elemento clicado também poderá ser transmitido como argumento.

Se o destino e o elemento não forem iguais, foi um evento que se propagou.

function myfunc(el){
  if (window.event.target === el){
      // perform action
  }
}
<div onclick="myfunc(this)" />

Obrigado companheiro, esta parece ser a solução mais limpa aqui. Em uma nota lateral, você deve considerar que isso só corresponde quando o elemento clicado é o elemento superior superior real.
— Simon Mattes

0
<div onclick="alert('you clicked the header')" class="header">
  <span onclick="alert('you clicked inside the header'); event.stopPropagation()">
    something inside the header
  </span>
</div>

0

A melhor solução seria lidar com o evento por meio de uma função javascript, mas para usar uma solução simples e rápida usando o elemento html diretamente e uma vez que o "event" e o "window.event" sejam descontinuados e não sejam universalmente suportados ( https://developer.mozilla.org/pt-BR/docs/Web/API/Window/event ), sugiro o seguinte "código rígido":

<div onclick="alert('blablabla'); (arguments[0] ? arguments[0].stopPropagation() : false);">...</div>
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.