2012-04-15 25 views
18

tengo el código HTML siguiente:jQuery evento On Click Div, Excepto Div Niño

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

que estoy tratando de hacerlo de modo que cuando los usuarios hacen clic en el div server que nos lleva a un diálogo de edición. El problema es simplemente hacer:

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

no funciona, porque si hacen clic en la X que es borrar, se abre el diálogo de edición. ¿Cómo se puede hacer que todo el div server tenga el evento click salvo el delete-server div.

+0

Debe tener en cuenta que su respuesta aceptada usa delegado eve sin una buena razón. puede leer 'on' [docs] (http://api.jquery.com/on/) para saber qué hace. – gdoron

+0

@gdoron - ¿Puede proporcionar una fuente para su reclamo de que la delegación de eventos es más lenta? AFAIK, la delegación del evento hace lo mismo que tú, pero detrás de escena; comprueba si el elemento objetivo coincide con el selector dado. Sin embargo, podría estar equivocado, y me encantaría estar iluminado. –

+0

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

Respuesta

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

Aquí está el violín: http://jsfiddle.net/9bzmz/3/

+0

gracias, aprendí algo nuevo de él ... :-) – Peeyush

+0

Aviso, haga clic en NOMBRE DEL SERVIDOR, ¿por qué la alerta se activa dos veces? http://jsfiddle.net/9bzmz/1/ – Justin

+0

@Justin, ¿entonces está mostrando 2 cuadros de alerta a su lado cuando haga clic en el nombre del servidor? – Peeyush

12

Sólo tienes que comprobar cuál es el elemento que desencadenó el evento:

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

LIVE DEMO

+0

Todavía veo el diálogo de edición al hacer clic en X, creo esto se debe a que el evento click se activa en '.server', por lo que no se conoce acerca de la div secundaria' .delete-server'. – Justin

+0

@Justin. Mira la respuesta actualizada. Debe tener en cuenta que su respuesta aceptada es un 'evento delegado' en lugar de' evento directo', que es más lento y no tiene ninguna razón para hacerlo. delegate event se debe usar para cambiar dinámicamente la estructura DOM. – gdoron

+0

¿Puede proporcionar una fuente para su reclamo de que la delegación de eventos es más lenta? AFAIK, la delegación del evento hace lo mismo que tú, pero detrás de escena; comprueba si el elemento objetivo coincide con el selector dado. Sin embargo, podría estar equivocado, y me encantaría estar iluminado. –

6

Hay una forma alternativa de resolver esto:

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

Solo asegúrese de que un evento de clic emitido en .delete-server no burbujea en el elemento principal.

+0

+1 Buena manera, aunque utiliza dos controladores mientras que se puede hacer con la comprobación del elemento 'objetivo'. [marque esto] (http://stackoverflow.com/a/10160231/601179) – gdoron

+0

@gdoron Sí, pero ¿dónde estaría la elegancia en esto? Eso llevaría a un controlador de eventos único con un control 'if' /' switch' dentro de él para determinar qué se supone que el evento * en realidad * se supone que debe hacer. Consideraría esto bastante mal. – Tomalak

+0

Bueno ... no hay un camino equivocado, me gusta el mío mejor. Cada forma es mejor que la respuesta aceptada que utiliza el evento de delegado sin una buena razón ... :) – gdoron

0

Esto solo funciona para mí.

js_object es jQuery objeto para padres meta como 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 su caso:

servidor - JS-matriz

delete-servidor - JS-niño-1

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

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