¿Cómo detener la propagación de eventos con el atributo onclick en línea?

313

Considera lo siguiente:

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

¿Cómo puedo hacer que cuando el usuario haga clic en el intervalo, no divactive el evento de clic del?

Sam
fuente

Respuestas:

272

Utilice event.stopPropagation () .

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

Para IE: window.event.cancelBubble = true

<span onclick="window.event.cancelBubble = true; alert('you clicked inside the header');">something inside the header</span>
James
fuente
11
No existe el objeto de evento en FireFox.
Robert C. Barth
66
El objeto de evento es un parámetro de la devolución de llamada. En realidad, no existe el objeto de evento en IE porque se puede acceder a este objeto a través de window.event en lugar de ser un parámetro de la función :-)
Vincent Robert
66
Esto es simplemente incorrecto: los controladores onclick en línea no hacen pasar el evento como argumento. La solución correcta es Gareths, a continuación.
Benubird
2
En Firefox, puede tener acceso a un evento variable en un script en línea, pero window.event no está disponible. <div onclick = "alert (event);"> </div>
Morgan Cheng
1
eventparece estar disponible en eventos en línea en IOS Safari también.
Yuval A.
210

Hay dos formas de obtener el objeto de evento desde una función:

  1. El primer argumento, en un navegador compatible con W3C (Chrome, Firefox, Safari, IE9 +)
  2. El objeto window.event en Internet Explorer (<= 8)

Si necesita admitir navegadores heredados que no siguen las recomendaciones del W3C, generalmente dentro de una función usaría algo como lo siguiente:

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

que verificaría primero uno, y luego el otro y almacenaría el que se encontrara dentro de la variable de evento. Sin embargo, en un controlador de eventos en línea no hay un eobjeto para usar. En ese caso, debe aprovechar la argumentscolección que siempre está disponible y se refiere al conjunto completo de argumentos pasados ​​a una función:

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

Sin embargo, en términos generales, debe evitar los controladores de eventos en línea si necesita algo complicado como detener la propagación. Escribir sus manejadores de eventos por separado y adjuntarlos a elementos es una idea mucho mejor a mediano y largo plazo, tanto para facilitar la lectura como para el mantenimiento.

Gareth
fuente
11
Desde un oyente en línea, puede pasar el objeto de evento como:, onclick="foo(event)"luego en la función function foo(event){/* do stuff with event */}. Esto funciona en los modelos de eventos IE y W3C.
RobG
55
Ese "menor o igual a ocho" es algo ... ambiguo.
TechNyquist
8
Esto en realidad no responde la pregunta.
jcomeau_ictx
1
respuesta ordenada a una pregunta diferente. : - /
Arel
80

Tenga en cuenta que window.event no es compatible con FireFox y, por lo tanto, debe ser algo similar a:

e.cancelBubble = true

O bien, puede usar el estándar W3C para FireFox:

e.stopPropagation();

Si quieres ponerte elegante, puedes hacer esto:

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

    //IE9 & Other Browsers
    if (e.stopPropagation) {
      e.stopPropagation();
    }
    //IE8 and Lower
    else {
      e.cancelBubble = true;
    }
}
Robert C. Barth
fuente
12
Y para que funcione, hay que llamar a esto así:<div onclick="myEventHandler(event);">
DarkDust
1
Podría ser "evento || window.event".
Puntiagudo
1
si (e.cancelBubble) no me parece correcto, lo configuras como verdadero si ya es cierto
Guillaume86
e.cancelBubbledevuelve falso en IE! No puede alcanzar las e.cancelBubble = true;instrucciones. ¡Use la condición de SoftwareARM en su lugar!
mauretto
45

Use esta función, probará la existencia del método correcto.

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

Tuve el mismo problema - cuadro de error js en IE - esto funciona bien en todos los navegadores hasta donde puedo ver (event.cancelBubble = true hace el trabajo en IE)

onClick="if(event.stopPropagation){event.stopPropagation();}event.cancelBubble=true;"
MSC
fuente
1
Gracias @MSC exactamente lo que necesitaba!
DannyC
1
Guión en línea. Responde la pregunta
Cesar
10

Esto funciono para mi

<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>
Matías Contreras Selman
fuente
¿Estás seguro de que este fragmento de código exacto te funcionó? Porque parece que hay un problema de comillas en el controlador onclick del div externo ...?!
Nicole
7

Para las páginas web ASP.NET (no MVC), puede usar el Sys.UI.DomEventobjeto como contenedor del evento nativo.

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

o, pase el evento como parámetro a la función interna:

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

y en alguna función:

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

No puedo comentar debido al Karma, así que escribo esto como una respuesta completa: De acuerdo con la respuesta de Gareth (var e = argumentos [0] || window.event; [...]) Usé este delineador en línea en el onclick para un pirateo rápido:

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

Sé que es tarde, pero quería hacerle saber que esto funciona en una sola línea. Las llaves devuelven un evento que tiene la función stopPropagation adjunta en ambos casos, por lo que intenté encapsularlas en llaves como en un if y ... funciona. :)

usuario3611941
fuente
1

Esto también funciona: en el enlace HTML, use onclick con return como este:

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

Y luego la función comfirmClick () debería ser como:

function confirmClick() {
    if(confirm("Do you really want to delete this task?")) {
        return true;
    } else {
        return false;
    }
};
Rajendra
fuente
2
Esto no es lo que significaba la pregunta.
jzonthemtn
@jbird Eso es exactamente lo que significa la pregunta. Es una forma diferente (más antigua) de cancelar un evento de burbujear el árbol de dom (está en las especificaciones de nivel 1 de api dom).
gion_13
@ gion_13 Pero la acción del clic no es algo que el usuario deba confirmar. En la pregunta, solo queremos que se active el onclick () del niño y no el onclick () del padre. Poner un mensaje de usuario entre esos no es útil. Espero que puedas ver esta diferencia.
jzonthemtn
1
El confirmno es relevante. Me refiero al valor de retorno . cita: En el enlace HTML, use onclick con return como este
gion_13
devolviendo cancelaciones falsas siguiendo el enlace, no cancela la propagación en mi Chrome
commonpike
1

¿Por qué no simplemente verificar en qué elemento se hizo clic? Si hace clic en algo, window.event.targetse asigna al elemento en el que se hizo clic, y el elemento en el que se hizo clic también se puede pasar como argumento.

Si el objetivo y el elemento no son iguales, fue un evento que se propagó hacia arriba.

function myfunc(el){
  if (window.event.target === el){
      // perform action
  }
}
<div onclick="myfunc(this)" />
cs01
fuente
Gracias amigo, esta parece ser la solución más limpia aquí. Sin embargo, en una nota al margen, debe tener en cuenta que esto solo coincide cuando el elemento que se hace clic es el elemento 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>
Pico común
fuente
0

La mejor solución sería manejar el evento a través de una función de JavaScript, pero para usar una solución simple y rápida usando el elemento html directamente, y una vez que el "evento" y "window.event" están en desuso y no son compatibles universalmente ( https://developer.mozilla.org/en-US/docs/Web/API/Window/event ), sugiero el siguiente "código duro":

<div onclick="alert('blablabla'); (arguments[0] ? arguments[0].stopPropagation() : false);">...</div>
jose.serapicos
fuente