2010-01-09 16 views
24

A veces quiero adjuntar algún tipo de metadatos a un nodo HTML y me pregunto, ¿cuál es la mejor manera de hacerlo?¿Cómo puedo adjuntar "metadatos" a un nodo DOM?

me puedo imaginar lo siguiente: atributos

  • no estándar: <div myattr1="myvalue1" myattr2="myvalue2" > (validación saltos)
  • volver a utilizar un atributo existente <div class="myattr1-myvalue2-myattr2-myvalue2"> (Requiere análisis y un cierto nivel de escapar)

¡Ambas soluciones son realmente feas!

¿Hay alguna manera de hacer esto de forma más elegante? Ya estoy usando jQuery, por lo que cualquier buena solución de Javascript, si alguna, también es apreciada.

Respuesta

11

Si no es necesario almacenar el atributo en el marcado, una gran solución es la función data de jQuery: http://docs.jquery.com/Core/data.

+0

Hasta que HTML se generalice, creo que esta es la mejor solución. –

+5

Quise decir "HTML 5" por supuesto :) –

+0

¿hay una forma estándar de hacer esto sin jQuery en javascript moderno? – TKoL

0

Si está utilizando xhtml, puede modificar su DTD para que validen sus atributos adicionales.

Si está utilizando html5, puede ir con los atributos de data-foobarbaz.

5

Una posible solución que quizás no coincida exactamente con sus requisitos es utilizar una clase como "repositorio de metadatos", con métodos para obtener/establecer datos basados ​​en la identificación de los elementos.

var metadataRepository = function(){ 
    this.elements = []; 

    this.set = function(id,key,value){ 
     this.elements[id][key] = value; 
    } 

    this.get = function(id,key){ 
     if (typeof(this.elements[id]) == "undefined"){ 
      return null; 
     } 
     if (key){ 
      return (this.elements[id][key] != "undefined") ? this.elements[id][key] : null; 
     } else { 
      return this.elements[id]; 
     } 
    } 

} 

var myMR = new metadataRepository(); 

myMR.set("myDiv1","attr1",232442); 
myMR.set("myDiv2","attr1",{"id":23,"name":"testName"}); 

... 

myMR.get("myDiv1","attr1"); //Returns only attr1 
myMR.get("myDiv2"); //Returns all attributes 
+0

O-ho, lo sé, dos años después, pero de todos modos gracias por compartir @amercader –

+0

@JoshGuzman No crees que seas la única persona que hace esta pregunta, ¿o sí? – Yaroslav

35

HTML 5 introduce la noción de custom data attributes, que cualquiera puede crear con el fin de unir personalizados, datos ocultos para elementos con fines de scripting. Simplemente cree un atributo usando un prefijo data-, como data-myattr1 o data-myattr2, y llénelo con sus datos.

<div data-myattr1="myvalue1" data-myattr2="myvalue2">Content</div> 

Lo bueno de esta solución es que ya funciona en todos los principales navegadores; todos analizarán los atributos desconocidos y los expondrán en el DOM para acceder mediante JavaScript. HTML5 agrega algunos mecanismos de conveniencia para acceder a ellos, que aún no se han implementado, pero solo puede usar el estándar getAttribute para acceder a ellos por el momento. Y el hecho de que estén permitidos en HTML5 significa que su código validará, siempre y cuando esté dispuesto a usar un borrador de estándar en lugar de uno aceptado (no creo que los atributos data- sean particularmente controvertidos, sin embargo, Me sorprendería si fueran eliminados del estándar).

La ventaja esto tiene sobre los atributos de espacios de nombres en XHTML es el IE no es compatible con XHTML, por lo que tendría que poner en práctica algo que pretende utilizar atributos de espacio de nombres, pero en realidad sólo utiliza atributos no válidos con un : en su nombre, que es cómo IE los analizaría. Es mejor que usar class, porque poner muchos datos en un atributo class lo sobrecarga bastante, e implica tener que realizar un análisis adicional para extraer diferentes datos. Y es mejor que crear uno propio (que funcionará en los navegadores actuales), porque está bien definido que estos atributos con el prefijo data- son datos privados para scripting, por lo que su código se validará en HTML5 y nunca entrará en conflicto con estándares futuros.

Otra técnica poco conocida para añadir datos personalizados a HTML, que es válido incluso en HTML 4, es la adición de script elementos con type atributos de algo que no sea text/javascript (o uno de la pareja de otros tipos que se pueden utilizar para especificar JavaScript). Estos bloques de script serán ignorados por los navegadores que no saben qué hacer con ellos, y usted puede acceder a ellos a través del DOM y hacer lo que quiera con ellos. HTML5 explicitly discusses this usage, pero no hay nada que lo invalide en versiones anteriores, y funciona en todos los navegadores modernos, hasta donde yo sé. Por ejemplo, si desea utilizar CSV para definir una tabla de datos:

<div> 
    <script type="text/csv;header=present"> 
    id,myattr1,myattr2 
    something,1,2 
    another,2,4 
    </script> 
    Content 
</div> 

Ésta es la técnica utilizada por SVG Web para permitir la incorporación de SVG en HTML, con la emulación a través de Flash si el navegador no soporta SVG nativo Actualmente, incluso los navegadores compatibles con SVG (Firefox, Safari, Chrome, Opera) no lo admiten directamente en línea en HTML, solo lo admiten directamente en línea en XHTML (porque los elementos SVG están en un espacio de nombres diferente). SVG Web le permite poner SVG en línea en HTML, usando una etiqueta de script, y luego transforma esos elementos en el espacio de nombres apropiado y los agrega al DOM, para que puedan representarse como XHTML. En navegadores que no son compatibles con SVG, también emula la función de los elementos mediante Flash.

3

Asumiendo XHTML, solo introduzca un nuevo espacio de nombres para sus propios metadatos. De esta forma, puede tener sus atributos en su propio espacio de nombres con nombres arbitrarios y no entrarán en conflicto con ninguna validación.

Básicamente todo lo que necesita es añadir

xmlns:myns="http://www.example.com/URI/to/myNamespaceDeclaration" 

al nodo raíz y entonces usted puede tener nodos como

<p myns:type="important">I'm a paragraph.</p> 

en cualquier lugar bajo esa raíz. Ese es esencialmente el propósito de los espacios de nombres, para permitir que el desarrollador agregue datos arbitrarios como capas para todo el modelo.

Editar:

también una nota rápida, class atributo es hoy en día utilizan una gran cantidad de microformats para fines de etiquetado de metadatos. Es posible que desee echar un vistazo al enlace de arriba para ver si alguien ya inventó la rueda que está tratando de encontrar :)

0

WeakMap podría hacer el truco. Es una estructura de datos tipo mapa donde las claves son objetos y los valores son valores arbitrarios.

const div = document.createElement("div") 
const metadata = new WeakMap() 
metadata.set(div, "div metadata") 
metadata.get(div) // "div metadata" 
Cuestiones relacionadas