¿Cómo evito que se active el evento onclick de un padre cuando se hace clic en un ancla secundaria?
Actualmente estoy usando jQuery para hacer que se pueda hacer clic en un div y en este div también tengo anclajes. El problema con el que me encuentro es que cuando hago clic en un ancla, ambos eventos de clic se activan (para el div y el ancla). ¿Cómo evito que se active el evento onclick del div cuando se hace clic en un ancla?
Aquí está el código roto:
javascript
var url = $("#clickable a").attr("href");
$("#clickable").click(function() {
window.location = url;
return true;
})
HTML
<div id="clickable">
<!-- Other content. -->
<a href="http://foo.example">I don't want #clickable to handle this click event.</a>
</div>
Los eventos se expanden hasta el punto más alto del DOM en el que se ha adjuntado un evento de clic. Entonces, en su ejemplo, incluso si no tuviera ningún otro elemento explícitamente en el que se pueda hacer clic en el div, cada elemento secundario del div expandiría su evento de clic en el DOM hasta que el controlador de eventos de clic del DIV lo detecte.
Hay dos soluciones para esto: verificar quién realmente originó el evento. jQuery pasa un objeto eventargs junto con el evento:
$("#clickable").click(function(e) {
var senderElement = e.target;
// Check if sender is the <div> element e.g.
// if($(e.target).is("div")) {
window.location = url;
return true;
});
También puede adjuntar un controlador de eventos de clic a sus enlaces que les indique que dejen de difundir eventos después de que se ejecute su propio controlador:
$("#clickable a").click(function(e) {
// Do something
e.stopPropagation();
});
Utilice el método stopPropagation , vea un ejemplo:
$("#clickable a").click(function(e) {
e.stopPropagation();
});
Como dice jQuery Docs:
stopPropagation
El método evita que el evento se propague en el árbol DOM, evitando que los controladores principales sean notificados del evento.
Tenga en cuenta que no impide que otros oyentes manejen este evento (por ejemplo, más de un controlador de clic para un botón); si no es el efecto deseado, debe usarlo stopImmediatePropagation
en su lugar.
Aquí mi solución para todos los que buscan un código que no sea jQuery (javascript puro)
document.getElementById("clickable").addEventListener("click", function(e) {
e = window.event || e;
if(this === e.target) {
// put your code here
}
});
Su código no se ejecutará si se hace clic en los hijos de los padres.
Si no tiene la intención de interactuar con los elementos internos en ningún caso , entonces una solución CSS podría resultarle útil.
Simplemente configure los elementos internos enpointer-events: none
en tu caso:
.clickable > a {
pointer-events: none;
}
o para apuntar a todos los elementos internos en general:
.clickable * {
pointer-events: none;
}
Este sencillo truco me ahorró mucho tiempo mientras desarrollaba con ReactJS.
La compatibilidad con el navegador se puede encontrar aquí: http://caniuse.com/#feat=pointer-events