2010-01-08 14 views
6

Este código de jQuery 1.3.2 añade un elemento a la página, se registra un evento de "clic", a continuación, quita y vuelve a unir el elemento:¿Por qué desaparecen los eventos registrados cuando se elimina un elemento de DOM?

var button = $('<button>Click me!</button>') 
    .click(function(){ alert("Hello") }) 
    .appendTo('body'); 

$('body').html(''); 

button.appendTo('body'); 

El botón aparece en la página como se esperaba, pero al hacer clic en él hace nada. Me gustaría saber por qué los controladores de eventos se eliminaron del objeto.

Nota: Tengo conocimiento de soluciones tales como jQuery.live() o clone(true) o usando appendTo sin una eliminación. Lo que estoy buscando es una explicación , no es una solución o una solución.

EDITAR: Supongo que esta podría ser una decisión de diseño arbitraria y contraintuitiva del DOM. Una explicación como "Porque esa es la forma en que la sección X de la especificación Y quiere que esté" estaría bien.

+0

Puede actualizar la pregunta con la versión que está utilizando, o es la misma entre 1.2.6, 1.3.2 y 1.4 alpha. –

Respuesta

6

Cuando elimina un elemento del DOM usando jQuery, se destruirán todos los datos (incluidos los manejadores de eventos) mantenidos por jQuery en ese elemento. Esto se hace para evitar fugas de memoria.

Esta no es una característica (o error) de la API de DOM. Es solo jQuery.

+0

¿Quieres decir, el error de referencia circular IE DOM-y-JS? Ya veo. Como curiosidad, ¿cómo jQuery detecta que el elemento fue eliminado del DOM? ¿Hay algún evento para eso? –

+1

jQuery solo "limpiará" los datos si elimina el elemento utilizando uno de los métodos de jQuery. Si solo usa 'button [0] .parentNode.removeChild (button [0])', jQuery no lo sabrá. – James

+1

Derecha. Entonces, 'html()' de jQuery también ejecuta una eliminación en todos los niños antes de configurar el nuevo contenido? Inteligente. Y otra razón más para no usar 'innerHtml' :) –

5

Si desea que sus eventos registrados permanezcan en su elemento, use .detach() en lugar de .remove(). Úselo de la misma manera que usaría .remove(), mantendrá sus eventos en su elemento.

+0

Gracias por señalar en esa dirección. Exactamente la función que necesitaba. – Chris

Cuestiones relacionadas