2010-01-09 3 views
24

Parfois, je veux joindre une sorte de méta-données à un nœud HTML et je me demandais, quelle est la meilleure façon de le faire.Comment puis-je attacher des "méta-données" à un noeud DOM?

Je peux imaginer ce qui suit:

  • attributs non standard: <div myattr1="myvalue1" myattr2="myvalue2" > (validation des pauses)
  • Re-utiliser un attribut existant <div class="myattr1-myvalue2-myattr2-myvalue2"> (nécessite l'analyse syntaxique et un certain niveau d'échapper)

Les deux solutions sont vraiment moche!

Y at-il un moyen de le faire plus élégamment? J'utilise déjà jQuery donc toute bonne solution Javascript, le cas échéant, est également appréciée.

Répondre

11

S'il n'est pas nécessaire de stocker l'attribut dans le balisage, une excellente solution est la fonction data de jQuery: http://docs.jquery.com/Core/data.

+0

Jusqu'à ce que le HTML se généralise, je pense que c'est la meilleure solution. –

+5

Je voulais dire "HTML 5" bien sûr :) –

+0

y at-il un moyen standard de faire cela sans jQuery en javascript moderne? – TKoL

0

Si vous utilisez xhtml, vous pouvez modifier votre DTD afin que vos attributs supplémentaires soient validés.

Si vous utilisez html5, vous pouvez utiliser les attributs data-foobarbaz.

5

Une solution possible qui ne correspond peut-être pas exactement à vos besoins est d'utiliser une classe comme "référentiel de métadonnées", avec des méthodes pour obtenir/définir des données en fonction de l'ID des éléments.

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, je sais, deux ans plus tard, mais de toute façon merci de partager @amercader –

+0

@JoshGuzman Vous ne pensez pas que vous êtes la seule personne à poser cette question, n'est-ce pas? – Yaroslav

35

HTML5 introduit la notion de custom data attributes, que tout le monde peut créer afin d'attacher sur mesure, des données cachées aux éléments à des fins de script. Créez simplement un attribut en utilisant un préfixe data-, tel que data-myattr1 ou data-myattr2, et remplissez-le avec vos données.

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

La bonne chose à propos de cette solution est qu'elle fonctionne déjà dans tous les principaux navigateurs; ils vont tous analyser les attributs inconnus et les exposer dans le DOM pour l'accès par JavaScript. HTML5 ajoute quelques mécanismes de commodité pour y accéder, qui n'ont pas encore été implémentés, mais vous pouvez simplement utiliser le standard getAttribute pour y accéder pour l'instant. Et le fait qu'ils soient autorisés en HTML5 signifie que votre code va valider, aussi longtemps que vous êtes prêt à utiliser un projet de norme par opposition à un standard accepté (je ne crois pas que les attributs data- sont particulièrement controversés, cependant, Je serais surpris s'ils étaient retirés de la norme). L'avantage que cela a sur les attributs namespaced dans XHTML est que l'IE ne supporte pas XHTML, donc vous devrez implémenter quelque chose qui prétend utiliser les attributs d'espace de nommage mais utilise simplement des attributs invalides avec un : dans leur nom, qui est comment IE les analyserait. C'est plus agréable que d'utiliser class, parce que mettre un grand nombre de données dans un attribut class le surcharge beaucoup et implique d'avoir à faire une analyse supplémentaire pour extraire différentes données. Et c'est mieux que de simplement créer le vôtre (qui fonctionnera dans les navigateurs actuels), car il est bien défini que ces attributs préfixés par data- sont des données privées pour le script, et donc votre code va valider en HTML5 et ne sera jamais en conflit avec les futures normes.

Une autre technique peu connue pour ajouter des données personnalisées à HTML, qui est valide même en HTML 4, est l'ajout script éléments avec type attributs de quelque chose autre que text/javascript (ou l'un des deux autres types qui peuvent être utilisés pour spécifiez JavaScript). Ces blocs de scripts seront ignorés par les navigateurs qui ne savent pas quoi faire avec eux, et vous pouvez y accéder via le DOM et faire ce que vous voulez avec eux. HTML5 explicitly discusses this usage, mais il n'y a rien qui le rend invalide dans les anciennes versions, et il fonctionne dans tous les navigateurs modernes autant que je sache. Par exemple, si vous souhaitez utiliser CSV pour définir une table de données:

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

C'est la technique utilisée par SVG Web pour permettre l'incorporation de SVG en HTML, avec l'émulation via Flash si le navigateur ne supporte pas SVG natif. Actuellement, même les navigateurs qui supportent SVG (Firefox, Safari, Chrome, Opera) ne le supportent pas directement en HTML, ils le supportent directement en XHTML (car les éléments SVG sont dans un espace de noms différent). SVG Web vous permet de mettre SVG en ligne en HTML, en utilisant une balise de script, puis il transforme ces éléments dans l'espace de nom approprié et les ajoute au DOM, afin qu'ils puissent être rendus en XHTML. Dans les navigateurs qui ne supportent pas SVG, il émule également la fonction des éléments en utilisant Flash.

3

En supposant XHTML, introduisez simplement un nouvel espace de noms pour vos propres métadonnées. De cette façon, vous pouvez avoir vos attributs dans leur propre espace de nom avec des noms arbitraires et ils ne seront pas en conflit avec une quelconque validation.

Fondamentalement, tout ce dont vous avez besoin est d'ajouter

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

au nœud racine, puis vous pouvez avoir des noeuds tels que

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

partout sous cette racine. C'est essentiellement le but des espaces de noms, pour permettre au développeur d'ajouter des données arbitraires en tant que couches à l'ensemble du modèle.

Edit:

également une note rapide, class attribut est aujourd'hui utilisé par microformats à des fins de marquage des métadonnées. Vous pouvez jeter un oeil au lien ci-dessus pour voir si quelqu'un a déjà inventé la roue que vous essayez de trouver :) :)

0

WeakMap pourrait faire l'affaire. C'est une structure de données semblable à une carte où les clés sont des objets et les valeurs sont des valeurs arbitraires.

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