2009-07-21 7 views
16

Estoy desarrollando código usando jQuery y necesito almacenar datos asociados con ciertos elementos DOM. Hay un montón de otras preguntas sobre cómo para almacenar datos arbitrarios con un elemento html, pero estoy más interesado en por qué elegiría una opción sobre la otra.Uso del almacén de datos de jQuery frente a las propiedades de expansión

Digamos, para simplificar el argumento, que quiero almacenar una propiedad "lineNumber" con cada fila en una tabla que sea "interesante".

opción 1 sería simplemente establecer una propiedad expando en cada elemento DOM (espero que estoy usando el término 'Expansión' correctamente):

$('.interesting-line').each(function(i) { this.lineNumber = i; }); 

Opción 2 sería el uso de los datos de jQuery() la función de asociar una propiedad con el elemento:

$('.interesting-line').each(function(i) { $(this).data('lineNumber', i); }); 

Haciendo caso omiso de cualquier otro deficiencias de mi código de ejemplo, ¿existen fuertes razones por las que elegiría un medio de almacenamiento de propiedades sobre el otro?

Respuesta

12

Si está creando un complemento, debe usar $.data. Si necesita almacenar el atributo con frecuencia y rara vez necesita consultar el DOM para él, entonces use $.data.

Una vez dicho esto para todas mis aplicaciones de cliente que tienden a almacenar atributos personalizados DOM en el elemento DOM a sí mismos para que pueda consultar posteriormente utilizando el atributo [] selector:

var domElement = $('.interesting-line[lineNumber=' + lineNumber + ']').get(0); 

Esto es mucho más legible que iterar el conjunto envuelto llamando al .data() en cada artículo. A menudo estoy interactuando con otra biblioteca de terceros que opera en un elemento DOM, por lo que tener acceso rápido y fácil al elemento DOM a través de este mecanismo mantiene el código legible.

Es tan fácil como almacenar una tabla de búsqueda mapeando lineNumbers a elementos, sin embargo, la técnica de atributo expando corre menos riesgo de perder memoria en comparación, ya que no está almacenando referencias a elementos DOM que necesita limpiar más adelante.

Update 5 años después acaba de leer esto después de que recibió una [merecido] downvote: por favor, ignora el texto tachado anteriormente. jQuery hace no consulta el DOM en función del conjunto de propiedades de expando, y no lo ha hecho por un tiempo. Entonces use $.data. No hay ninguna razón para contaminar el DOM cuando no hay un uso pragmático para hacerlo.

+2

Hay [un plugin jQuery] (http://plugins.jquery.com/files/jquery.dataSelector.js.txt) que le permite usar selectores como en var 'domElement = $ ('. Interesting-line: data (" lineNumber = '+ lineNumber +' ")) get (0);' – ErikE

2

El uso de $.data no modifica el DOM. Debe usar $.data. Si está creando un complemento, debe almacenar un objeto en $.data con propiedades en ese objeto en lugar de almacenar cada una de esas propiedades como pares clave/valor diferentes en la estructura $.data.

+2

tenga en cuenta que así es como funcionan los repositorios $ .data, por lo que solo está agregando un nivel adicional de direccionamiento indirecto. si asesora sobre esto debido al aislamiento del espacio de nombres, puede hacerlo con la misma eficacia con un prefijo específico del complemento. concedido, esto solo sería importante si se almacenan muchos datos y/o se accede a ellos en un ciclo cerrado. en cualquier otro lado, es una cuestión de preferencia de estilo – Javier

+1

Sí, evitaría modificar el DOM. IIRC, puede causar algunas pérdidas de memoria bastante malas en algunos navegadores. – seth

+0

@Javier: Estaba retransmitiendo lo que aconseja la documentación de $ .data. Estoy de acuerdo en que la capa adicional de indirección no parece tan valiosa, pero los documentos indican su mejor práctica. –

21

El uso de $.data lo protegerá de fugas de memoria.

En IE, cuando asigna un objeto javascript a una propiedad expando en un elemento DOM, los ciclos que cruzan ese enlace no son basura. Si su objeto javascript contiene una referencia al objeto dom, se perderá todo el ciclo. Es completamente posible terminar con referencias ocultas a objetos DOM, debido a cierres, por lo que puede filtrarse sin darse cuenta.

El almacén de datos jQuery está configurado para evitar la formación de estos ciclos. Si lo usa, no perderá memoria de esta manera. Su ejemplo no se filtrará porque está poniendo primitivas (cadenas) en el elemento DOM. Pero si coloca un objeto más complejo allí, corre el riesgo de tener una fuga.

Use $.data para que no tenga que preocuparse.

+0

Esto se aplica solo a IE7-, ¿verdad? – thorn

+0

¡Sin duda es mucho menos necesario en 2017 que en 2011! Creo que IE8 tiene el mismo problema, y ​​está solucionado en IE9, pero realmente no lo sé. –

+0

Sería muy práctico adjuntar datos directamente a los elementos. Mucho más simple que rastrear las pérdidas de memoria de jQuery causadas por '$ .data'. – thorn

Cuestiones relacionadas