2012-09-17 22 views
22

digamos que tenemos una estructura HTML de la siguientecaso Mastering burbujeante

<div id="container"> 
    <div id="nested"> 
     <span id="someElement"></span> 
    </div> 
</div> 

... y nuestra meta es tener un detector de eventos en el #containerúnica! Por lo tanto, nos atamos a un oyente (código de jQuery)

$("#container").on('click', function(event) { 
    alert("container was clicked"); 
}); 

que funciona, por supuesto, pero mi problema con este enfoque es que, ya que los eventos generalmente brotan, ese oyente también se disparará si realmente haga clic en #nested o #someElement . Mi solución actual a única manejar el clic cuando la #container se hace clic es comparar this con event.target

$("#container").on('click', function(event) { 
    if(this === event.target) { 
     alert("container was clicked"); 
    } 
}); 

Mi pregunta: ¿Es que considera "la mejor práctica"? ¿Hay una mejor manera con jQuery para lograr el mismo resultado "fuera de la caja"?

Ejemplo de acción: http://jsfiddle.net/FKX7p/

+3

OMI, esta es la mejor práctica. – VisioN

+0

@jSang: En realidad, los elementos internos no tienen ningún oyente al hacer clic. ¿Eso se considera la mejor práctica? unir cada elemento solo para detener la propagación? –

+0

No veo ningún enfoque mejor tampoco, de hecho, estaba a punto de publicar eso como respuesta hasta que vi que ya tienes ese código. –

Respuesta

0

solución alternativa:

$("#container").click(function(){ 
    alert("container was clicked"); 
}).children().click(function(e) { 
    return false; 
}); 

Pero su solución es mejor. jsfiddle.net/FKX7p/2/ (con falso retorno) O jsfiddle.net/FKX7p/3/ (usando stopPropagation)

que prefieren el uso de retorno en su ejemplo (código se vuelve más fácil de leer):

if(this !== event.target) return; 
+1

Además, use 'event.CurrentTarget! == event.Target' en lugar de' this' cuando sea necesario, debido al posible cambio de contexto de 'this' cuando se usa jQuery.proxy: http://api.jquery.com/jQuery .proxy/ – Nope

+0

La solución alternativa es peor, ya que agrega muchos controladores de eventos. – naugtur

+0

@naugtur Estoy de acuerdo con usted, pero antes de la función 'on' esta solución era popular. – webdeveloper

0

No estoy seguro de cuál obra de más rápido pero hago sentido de que el siguiente código será mejor:

$("#container").click(function (e) { 
    if (e.target.id && e.target.id !== "container") return false; 
}); 
+0

Ahora solo verifico el identificador, con selectores complejos no puedo ver de otra manera excepto comparando los objetos –

2

Una forma alternativa para evitar eventos de burbujeo es utilizar event.stopPropagation();

$("#container").on('click', function(event) { 
    alert("container was clicked"); 
}) 
.children().on('click', function(event) { 
    event.stopPropagation(); 
}); 

creo que la ventaja de usar este método es que si quieres adjuntar otro evento para el div anidado, sólo puede utilizar

$("#nested").on('click', function(event) { 
    event.stopPropagation(); 
    // some action 
}); 

$("#container").on('click', function(event) { 
    alert("container was clicked"); 
});​