2012-04-15 21 views
18

ho il seguente codice HTML:jQuery evento Click On Div, Salvo Bambino Div

<div class="server" id="32"> 
    <a>Server Name</a> 
    <div class="delete-server">X</div> 
</div> 

che sto cercando di fare in modo, quando gli utenti fanno clic sul server div si porta in primo piano una finestra di modifica. Il problema è semplicemente fare:

$(".server").click(function() { 
    //Show edit dialog 
}); 

non funziona, perché se si fa clic sulla X che è cancellare, si porta in primo piano la finestra di dialogo di modifica. Come si può fare in modo che l'intero div server abbia l'evento click eccetto il div delete-server.

+0

È necessario essere consapevoli del fatto che la risposta accettata utilizza la vigilia del delegato nt per nessuna buona ragione. puoi leggere 'on' [docs] (http://api.jquery.com/on/) per imparare cosa fa. – gdoron

+0

@gdoron - Puoi fornire una fonte per la tua richiesta che la delega degli eventi sia più lenta? AFAIK, la delegazione di eventi fa la stessa cosa che hai fatto, ma dietro le quinte; controlla se l'elemento di destinazione corrisponde al selettore indicato. Potrei avere torto però, e mi piacerebbe essere illuminato. –

+0

correlati http://stackoverflow.com/questions/12690313/jquery-on-click-on-everything-but-a-div-and-its-children/12690357 –

risposta

21
$(".server").on('click', ':not(.delete-server)', function (e) { 
    e.stopPropagation() 
    // Show edit dialog 
}); 

Ecco il violino: http://jsfiddle.net/9bzmz/3/

+0

grazie ho imparato qualcosa di nuovo da questo .. :-) – Peeyush

+0

Avviso, fare clic su SERVER NAME, perché l'avviso si attiva due volte? http://jsfiddle.net/9bzmz/1/ – Justin

+0

@Justin quindi mostra 2 caselle di avviso al tuo fianco quando fai clic su Nome SERVER? – Peeyush

12

Basta controllare qual è l'elemento che ha generato l'evento:

$(".server").click(function(e) { 
    if (!$(e.target).hasClass('delete-server')) { 
     alert('Show dialog!'); 
    } 
});​ 

LIVE DEMO

+0

Ancora vedendo la finestra di dialogo di modifica in arrivo quando si fa clic su X, penso questo perché l'evento click si attiva su '.server' in modo che non conosca il div child' .delete-server'. – Justin

+0

@Justin. Controlla la risposta aggiornata. Dovresti essere consapevole che la tua risposta accettata crea un 'delegate event' invece di' direct event', che è più lento e non ha motivo di farlo. l'evento delegato dovrebbe essere utilizzato per modificare dinamicamente la struttura DOM. – gdoron

+0

Puoi fornire una fonte per la tua richiesta che la delega degli eventi sia più lenta? AFAIK, la delegazione di eventi fa la stessa cosa che hai fatto, ma dietro le quinte; controlla se l'elemento di destinazione corrisponde al selettore indicato. Potrei avere torto però, e mi piacerebbe essere illuminato. –

6

C'è un modo alternativo per risolvere questo:

$(".server").click(function() { 
    // show edit dialog 
}); 
$(".delete-server").click(function (event) { 
    // show delete dialog for $(this).closest(".server") 
    event.stopPropagation(); 
}); 

Assicurati solo che un evento click pubblicato su .delete-server non diventi l'elemento principale.

+0

+1 Bel modo, anche se usa due gestori mentre può essere fatto controllando l'elemento 'target'. [controllare questo] (http://stackoverflow.com/a/10160231/601179) – gdoron

+0

@gdoron Sì, ma dove sarebbe l'eleganza in questo? Ciò porterebbe a un singolo gestore di eventi con un controllo 'if' /' '' al suo interno per determinare cosa l'evento è * effettivamente * dovrebbe fare. Lo considererei piuttosto puzzolente. – Tomalak

+0

Beh .. non c'è un modo sbagliato, mi piace il mio meglio. Ogni modo è migliore della risposta accettata che utilizza l'evento delegato senza una buona ragione ... :) – gdoron

0

Solo questo funziona per me.

js_object è oggetto jQuery per meta genitore come un $('body')

jq_object.on('click', '.js-parent :not(.js-child-1, .js-child-2)', function(event) { 
    //your code 
}); 

jq_object.on('click', '.js-child-1', function(event) { 
    //your code 
}); 

jq_object.on('click', '.js-child-2', function(event) { 
    //your code 
}); 

Fore vostro caso:

del server - js-genitore

delete-server - js-bambino-1

jq_object.on('click', '.server :not(.delete-server)', function(event) { 
    //your code 
}); 

jq_object.on('click', '.delete-server', function(event) { 
    //your code 
});