2012-06-09 10 views
39

Tengo una página usando jquery-ui-dialog. Cada vez que se abre el diálogo, los contenidos de la página se cargan usando ajax. Luego vincula algún evento usando jquery "on()". Cuando se cierra el cuadro de diálogo, vaciará su contenido.¿Debo desvincular el evento jquery antes de eliminar el elemento?

La pregunta es, ¿debo desvincular los eventos en ".ajax-content" antes de $ .empty()?

edición: preocupación 1. cualquier posible degradación de rendimiento JS? si vacío() cientos de nodos de esta manera.

preocupación 2. eliminaría elemento también eliminar eventos de la memoria (o lo que sea de ejecución/cadena de evaluación de jQuery)?

No les estoy haciendo nada por el momento. Si el cuadro de diálogo abrir/cerrar muchas veces sin actualización de página, ¿causaría algún problema?

mirada código como este:

<div id="jquery-dialog" class="container"> 
    <div class="ajax-content"> 
    some buttons.... 
    </div> 
</div> 

------after each ajax load------------ 
$(".ajax-content").on("click", ".button", function(event) { 
    //handles the click 
}); 

------on dialog close------------ 
$("#jquery-dialog").empty(); 
+3

+1: ¡Qué buena pregunta? Me preocupa esto también – vietean

Respuesta

43

Hola, sé que esta es una respuesta antigua, pero creo que la respuesta aceptada es engañosa.

Aunque es correcto decir que tendrá que desvincular eventos en JS sin formato para evitar pérdidas de memoria en navegadores antiguos (ehem IE), llamar a remove() o vaciar() ya lo hará por usted.

Así la llamada actual para vaciar() debería ser suficiente, que no necesita ser precedido por unbind()

a partir de documentos de jQuery (http://api.jquery.com/empty/)

Para evitar pérdidas de memoria, jQuery elimina otras construcciones, como los manejadores de datos y eventos, de los elementos secundarios antes de eliminar los elementos.

+1

Gracias por la respuesta. – Reed

+0

Gracias ... conciso, al punto, y la referencia de documentación proporcionada. +1 – greaterKing

1

Es mejor para desenlazar pero imprescindible.

La mayoría de los navegadores manejan esto correctamente y eliminan esos manejadores ellos mismos.

También puede ver do-i-need-to-remove-event-listeners

mejor manera de manejar este problema, puede utilizar el Delegado de eventos.

+0

Gracias por el enlace. Aprendí algo nuevo. – Reed

-1

La respuesta de Oscar es incompleta, si dentro de su parcial (vista que se carga a través de ajax) adjuntó eventos usando .on(), entonces debe llamar a .off() antes de .empty().

Mire en el siguiente código, si no se llama a .off(), los eventos asignados en p1.html a través del controlador estándar .click() se eliminan al llamar a .empty(), pero los eventos se asignan en p2.html a través de. on() no se eliminan y se vuelven a asignar cada vez que se carga el parcial.

índice.html

<html> 
<body> 
<script src="ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script> 
    <div id='spi' style="padding: 20px; border: 1px solid #666;"> 
    </div> 
    <br/> 
    <a href="p1.html" class="spi">Load Partial 1</a> | 
    <a href="p2.html" class="spi">Load Partial 2</a> 
    <script type="text/javascript"> 
    $(document).on('click', 'a.spi' , function(e) { 
     e.preventDefault(); 

     /* 
     !!! IMPORTANT !!! 
     If you do not call .off(), 
     events assigned on p2.html via .on() 
     are kept and fired one time for each time p2.html was loaded 
     */ 

     $("#spi").off(); 


     $("#spi").empty(); 
     $("#spi").load($(this).attr('href')); 
    }); 
    </script> 
</body> 
</html> 

p1.html

This is the partial 1<br/> 
<br/> 
<br/> 
<a href="javascript:void(0)" id='p1_l1'>Link 1</a> 
<br/><br/> 
<a href="javascript:void(0)" id='p1_l2'>Link 2</a> 
<br/><br/> 
<a href="javascript:void(0)" id='p1_l3'>Link 3</a> 


<script type="text/javascript"> 
    $("#p1_l1").click(function(e) { 
     e.preventDefault(); 
     console.debug("P1: p1_l1"); 
    }); 
    $("#p1_l2").click(function(e) { 
     e.preventDefault(); 
     console.debug("P1: p1_l2"); 
    }); 
</script> 

p2.html

This is the partial 2<br/> 
<br/> 
<br/> 
<a href="javascript:void(0)" id='p2_l1'>Link 1</a> 
<br/><br/> 
<a href="javascript:void(0)" id='p2_l2'>Link 2</a> 


<script type="text/javascript"> 
    $("#spi").on('click', 'a', function(e) { 
     e.preventDefault(); 
     console.debug('P2: ' + $(this).attr('id')); 
    }); 
</script> 
+0

En su llamada a .on() en p2.html, el evento se adjunta a '#spi' (no a los elementos 'a' internos). Cuando entonces .empty() lo hace más tarde, está desvinculando los eventos adjuntos a los elementos 'a' pero persisten los de '#spi'. Creo que si vuelve a escribir $ ("# spi"). On ('clic', 'a', función) a $ ("# spi a"). on ('clic', función) tendrá el efecto que desee. – Oscar

Cuestiones relacionadas