2010-03-02 15 views
154

Ho un div a cui ho allegato un evento onclick. in questo div c'è un tag con un link. Quando clicco sul link viene attivato anche l'evento onclick dal div. Come posso disabilitare questo in modo che se il collegamento è cliccato sul div onclick non viene licenziato?jquery stop figlio che attiva l'evento genitore

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> 

risposta

344

fare questo:

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

Se si desidera read more on .stopPropagation(), look here.

+2

se aiuta qualcuno, ho sostituito '$ (" header a. ")' Con '$ (".header * ")' e ha selezionato qualsiasi figlio (div, form, input, ecc.) –

+0

e.stopPropagation(); deve essere scritto sulla prima riga, a meno che non funzioni! – ehsan

+3

@ehsan Intendevi: "o non funzionerà "? –

0

O questo:

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

Nessun punto che passa in (e) se stai restituendo false. – Halcyon991

+2

@ Halcyon991 e viene passato in entrambi gli argomenti, e è solo un riferimento – qodeninja

+0

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

15

Modo migliore utilizzando on() con il concatenamento come,

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

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

Supponiamo di avere una galleria fotografica con uno sfondo oscurato e le foto centrate nel browser. Quando fai clic sullo sfondo nero (ma non all'interno di esso), vuoi che la sovrapposizione si chiuda.

Ecco qualche possibile 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 dovrebbe funzionare il JavaScript:

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

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

Questo fermerà gli eventi click da elementi all'interno .contents da ogni ricerca .gallery così la galleria chiuderà solo quando si fa clic nell'area dello sfondo nero sbiadito, ma non quando si fa clic nell'area dei contenuti. Questo può essere applicato a molti scenari diversi.

1

Un più breve modo per farlo:

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

O, piuttosto che avere un gestore eventi in più per evitare che un altro gestore, è possibile utilizzare l'argomento Event Object passato al gestore di eventi click per determinare se un bambino è stato cliccato target sarà l'elemento cliccato e currentTarget sarà 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(); 
}); 
+1

Per me questa è una soluzione più elegante in quanto non è necessario aggiungere un preventivo preventDefault() a ogni elemento figlio. –

+1

E funziona se si hanno eventi indipendenti sul bambino a differenza della risposta accettata. Soluzione decisamente più pulita e migliore –

+2

Nella maggior parte dei casi non ti importa di questo, ma se per qualsiasi motivo hai bisogno di supportare IE6-8, loro [non hanno 'currentTarget'] (https://developer.mozilla.org/en -US/docs/Web/API/eventi/currentTarget). Una soluzione alternativa è sostituirla con 'this', come suggerito in [un'altra risposta] (http://stackoverflow.com/a/6411507/2737565). –

0

mi sono imbattuto su questa domanda, alla ricerca di un'altra risposta.

Volevo impedire a tutti i bambini di attivare il genitore.

Questo è il più facile, metodo più leggibile per questo:

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