tag link body javascript jquery onclick

javascript - link - ¿Es malo tener manejadores de clics anidados?



noscript tag (4)

Alguien me mencionó esto una vez, pero nunca encontré documentación para respaldar el reclamo. ¿Es malo tener manipuladores de clics anidados en una aplicación? Por ejemplo:

$("div").on("click", function(){ //*Do things* $("p").on("click", function(){ //*Do things* }) })

Si es una mala práctica, ¿por qué y cuál sería una mejor solución?


"¿Es una mala práctica?" : Sí, porque la asignación de memoria ocurrirá condicionalmente, lo que siempre se considera malo debido a la rotación de GC. También promueve una lógica defectuosa, que depende cada vez más de la capacidad del lenguaje para comprenderlo en lugar de que usted entienda el idioma.

"¿Cuál sería una mejor solución?" : Registre los manejadores de eventos que sean necesarios, aplique la lógica dentro del manejador para ejecutar en base a las variables condicionales, que son establecidas por el otro manejador (es)

IE: Handler b se establece condicionalmente cuando sucede el evento a. En cambio: Handler a se establece con un código que establece una variable referenciada en Handler b. Handler b también está configurado. El evento b dispara pero se ejecuta de forma condicional en función de la variable a la que se hace referencia.


Es malo porque en tu ejemplo, cada vez que haces clic en "div" agregarás un nuevo controlador a "p". Haga clic en tres "divs" antes de hacer clic en "p" y el controlador de eventos "p" se ejecutará tres veces.

Una forma de evitar esto es usar un delegado:

$(document).delegate("p", "click", function () { /* do stuff */ });

Otra forma es desvincular los manejadores existentes y luego volver a vincularlos:

$("p").off(); $("p").on("click", function () { });

Una tercera forma es usar indicadores sucios (que deberán establecerse como globales, lo cual no es exactamente una mejor práctica) para verificar y ver si un controlador ya está trabajando en esa llamada a evento:

$("p").on("click", function () { if (flag) { return; } else { flag = true; doStuff(); flag = false; } });


Sí, es una mala práctica. La razón es que hay múltiples clics en los resultados div en los que tiene múltiples eventos agregados al otro elemento. Haga doble clic en el exterior y tendrá dos eventos de clics agregados a la etiqueta de párrafo.

Si realmente desea tener los clics agregados así, debe desvincular cualquier evento ya agregado.

$("div").on("click", function(){ //*Do things* $("p").off("click.myNameSpace").on("click.myNameSpace", function(){ //*Do things* }) });

Otra opción es agregar eventos y poner lógica dentro del clic para ver si se supone que se debe ejecutar.

(function () { var isActive = false; $("div").on("click", function(){ isActive = false; }); $("p").on("click", function(){ if (isActive) { isActive = false; console.info("The p was clicked"); } }); }());


Sí, generalmente es malo, a menos que eso sea exactamente lo que quieres.

Si alguien hace clic en un div dos veces, el manejador de eventos del párrafo se adjunta dos veces, haciendo "cosas" dos veces, pruébalo

$(''div'').on(''click'', function() { $(''p'').on(''click'', function() { alert(''This is annoyning''); }); });

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div>click me a few times ?</div> <br /><br /><br /> <p>... then click me</p>

Una mejor solución sería simplemente no anidar los controladores de eventos

var isClicked = false; $(''div'').on(''click'', function() { isClicked = true; }); $(''p'').on(''click'', function() { if (isClicked) // do stuff });

(simplificado para mostrar el concepto, no use variables globales, jQuery tiene data() )