jquery interrompe figlio attivando l'evento genitore


208

Ho un div a cui ho allegato un onclickevento. in questo div c'è un tag con un link. Quando faccio clic sul collegamento, onclickviene attivato anche l' evento dal div. Come posso disabilitarlo in modo tale che se il link viene cliccato sul div onclicknon viene attivato?

script:

$(document).ready(function(){
    $(".header").bind("click", function(){
         $(this).children(".children").toggle();
    });
})

codice html:

<div class="header">
    <a href="link.html">some link</a>
    <ul class="children">
        <li>some list</li>
    </ul>
</div>

Risposte:


412

Fai questo:

$(document).ready(function(){
    $(".header").click(function(){
        $(this).children(".children").toggle();
    });
   $(".header a").click(function(e) {
        e.stopPropagation();
   });
});

Se vuoi leggere di più su .stopPropagation (), guarda qui .


2
se aiuta qualcuno, ho sostituito $(".header a")con $(".header *")e ottenuto ogni bambino selezionato (div, forme, di ingresso, ecc).
aldo.roman.nurena,

1
e.stopPropagation (); deve essere scritto in prima riga, a meno che non funzioni!
Ehsan,

2
purtroppo questo metodo impedisce il relfunzionamento della lightbox configurata
eapo

5
La risposta sotto di xr280xr è molto migliore, in quanto non interferisce con i possibili eventi dei bambini.
Alexander Jank

1
Crei più problemi di quanti ne risolva. Immagina plug-in di terze parti che ascoltano l'evento click sull'elemento del documento. Non sapranno mai di quei clic. Vedi il commento su lightbox.
Salman A

100

Oppure, anziché disporre di un gestore eventi aggiuntivo per impedire un altro gestore, è possibile utilizzare l' argomento Event Event passato al gestore eventi click per determinare se è stato fatto clic su un figlio. targetsarà l'elemento cliccato e currentTargetsarà il div .header:

$(".header").click(function(e){
     //Do nothing if .header was not directly clicked
     if(e.target !== e.currentTarget) return;

     $(this).children(".children").toggle();
});

8
Per me questa è una soluzione più elegante poiché non è necessario aggiungere un preventDefault () esplicito a ogni elemento figlio.
Ryan Griggs,

5
E funziona se hai eventi indipendenti sul bambino a differenza della risposta accettata. Soluzione decisamente più pulita e migliore
BozanicJosip,

2
Nella maggior parte dei casi non ti interesserà di questo, ma se per qualsiasi motivo devi supportare IE6-8, non ce l'hannocurrentTarget . Una soluzione alternativa è sostituirla con this, come suggerito in un'altra risposta .
Alexander Jank

Questa è una soluzione più pulita rispetto all'impostazione di un ascoltatore aggiuntivo per catturare solo i clic.
Micros,

questo codice ha funzionato meglio per me` var target = $ (e.target); if (! target.is ("span")) return; `
Cr1xus

17

Modo migliore usando on () con concatenamento come,

$(document).ready(function(){
    $(".header").on('click',function(){
        $(this).children(".children").toggle();
    }).on('click','a',function(e) {
        e.stopPropagation();
   });
});

4

Le risposte qui hanno preso la domanda del PO in modo troppo letterale. In che modo queste risposte possono essere espanse in uno scenario in cui ci sono MOLTI elementi figlio, non solo uno<a> tag? Ecco un modo.

Supponiamo che tu abbia una galleria fotografica con uno sfondo oscurato e le foto centrate nel browser. Quando fai clic sullo sfondo nero (ma non al suo interno), vuoi che l'overlay si chiuda.

Ecco alcuni possibili HTML:

<div class="gallery" style="background: black">
    <div class="contents"> <!-- Let's say this div is 50% wide and centered -->
        <h1>Awesome Photos</h1>
        <img src="img1.jpg"><br>
        <img src="img2.jpg"><br>
        <img src="img3.jpg"><br>
        <img src="img4.jpg"><br>
        <img src="img5.jpg">
    </div>
</div>

Ed ecco come funzionerebbe JavaScript:

$('.gallery').click(
    function()
    {
        $(this).hide();
    }
);

$('.gallery > .contents').click(
    function(e) {
        e.stopPropagation();
    }
);

Ciò interromperà gli eventi di clic dagli elementi all'interno .contentsdi ogni ricerca in .gallerymodo che la galleria si chiuda solo quando si fa clic nell'area di sfondo nero sbiadito, ma non quando si fa clic nell'area del contenuto. Questo può essere applicato a molti scenari diversi.


4

Mi sono imbattuto in questa domanda, cercando un'altra risposta.

Volevo impedire a tutti i bambini di innescare il genitore.

JavaScript:

document.getElementById("parent").addEventListener("click",  function (e) {
    if (this !== event.target) return;
    // Do something
});

jQuery:

$("#parent").click(function () {
    // Do something
}).children().on("click", function (e) {
    e.stopPropagation();
});

0

O questo:

$(document).ready(function(){
    $(".header").click(function(){
        $(this).children(".children").toggle();
    });
   $(".header a").click(function(e) {
        return false;
   });
});

2
@ Halcyon991 e viene passato in entrambi i modi attraverso argomenti, e è solo un riferimento
qodeninja

@qodeninja Sì, ma un'aggiunta di carattere inutile se non viene utilizzata.
Halcyon991,

Inutile aggiungere return falseal link, dovrebbe essere cliccabile.
eapo,

0

La soluzione più semplice è aggiungere questo CSS ai bambini:

.your-child {
    pointer-events: none;
}

Ne avevo bisogno per il tag di carattere indesiderato aggiunto da Wordpress e ha funzionato per me
Ndm Gjr

-1

Un modo più breve per farlo:

$('.header').on('click', function () {
    $(this).children('a').on('click', function(e) {
        e.stopPropagation();
        $(this).siblings('.children').toggle();
    });
});

Ma ... Questo non fa nulla quando si fa clic sull'intestazione.
Liora Haydont,

Ogni volta che fai clic sull'intestazione, questo aggiunge un nuovo evento click ai figli ('a').
Frank Forte,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.