Niveau Niveau débutant

Attributs data-* et API dataset

Articlehtml

Publié par le , mis à jour le (201201 lectures)

html5 getattribute setattribute dataset data

HTML5 permet d'associer des données directement dans un élément HTML à l'aide des attributs data-*.

Comment peut-on associer des données quelconques à un élément HTML ? Dans ses premières spécifications, le langage ne laisse que peu de liberté : tous les attributs que l'on peut ajouter à un élément ont un usage précis. Il ne serait pas possible d'écrire : <img src="photo.jpg" auteur="Simon" date="15 février 2012"> pour ajouter des informations, car ce n'est pas valide.

Des attributs que l'on pourrait penser de premier abord inoffensifs visuellement ont souvent été détournés de leur usage initial, pour y stocker arbitrairement des données. C'est par exemple le cas de alt pour une image, ou de rel et title. Cet usage est à proscrire : les navigateurs et moteurs d'indexation pourraient interpréter de façon erronée des informations qui ont été placées à tort dans ces attributs, dont le rôle est pourtant bien défini, sans compter des effets indésirables sur l'accessibilité du document.

Heureusement, HTML5 permet d'écrire librement tout attribut débutant par data- et de s'affranchir de cette limitation. La page sera valide aux yeux du navigateur, en ayant pris la précaution d'utiliser le doctype HTML5 : <!DOCTYPE html>

Syntaxe

<element data-kiwi="info_associée"> ... </element>

On peut ainsi personnaliser la famille d'attributs débutant par data- en y concaténant une chaine de texte, à notre convenance (ici kiwi). Seules consignes : au moins un caractère et aucune majuscule. Il est bien sûr autorisé de cumuler plusieurs attributs data- sur un même élément.

Intérêt et application

L'intérêt principal est de simplifier le stockage des données dans le document directement dans un élément. Par exemple, dans une galerie d'images on peut stocker : le nom de l'auteur, le lieu... dans l'image elle-même, puis afficher ces informations au survol.

exemple avec une image

Cela permet de ne pas avoir à les stocker ailleurs, notamment dans un tableau JavaScript. Les cas pratiques sont nombreux, autant pour améliorer l'expérience utilisateur que construire des interfaces visuellement plus riches en combinant informations et scripts variés.

<img src="mamoto.jpg" alt="Une moto rouge"
  data-auteur="Simon" data-lieu="Strasbourg"
  data-materiel="EOS" data-gps="48.582967,7.74828">

On peut imaginer stocker ainsi toutes sortes de données, à partir du moment où il s'agit de chaînes de texte, et de les exploiter ensuite avec un script (sous-titres vidéo, variables pour ajax, paramètres d'animations...). Cependant il faut veiller à ne pas en abuser, une grande liberté implique de grandes responsabilités. Voici quelques limites :

  • Si des éléments plus appropriés existent, il faut les privilégier. L'élément time est, entre autres, prévu pour cela.
  • Les attributs data-ne sont pas pensés pour être utilisés par des entités extérieures (robots des moteurs de recherche, autres applications web qui ont été développées par des tiers) contrairement au microformats ou à Microdata, car il n'y a aucune standardisation des valeurs donc ces attributs sont ignorés par le navigateur.
  • Ne pas utiliser data- pour styler un élément en CSS de façon détournée ou stocker des informations essentielles à la compréhension du document.
  • Veillez à prendre quelques précautions pour le nommage : il est fort possible qu'un attribut aussi commun que data-width soit utilisé et modifié par d'autres scripts embarqués sur votre document. Pensez à inclure votre propre préfixe, par exemple data-alsa-width.

Utilisation avec JavaScript

Les APIs destinées à manipuler les attributs data en JavaScript font partie de la spécification HTML5. La propriété dataset doit permettre d'interagir avec les données. Chaque attribut data devient lui-même membre de dataset (en omettant le préfixe data-).

<img src="mamoto.jpg" alt="Une moto rouge" id="moto"
  data-auteur="Simon" data-lieu="Strasbourg"
  data-materiel="EOS" data-gps="48.582967,7.74828">

<script>
var monelement = document.getElementById('moto');

// Lecture d'une valeur
var auteur = monelement.dataset.auteur;

// Modification d'une valeur
monelement.dataset.gps = '49.04777,7.440491';

// Suppression
monelement.dataset.gps = null;
</script>

L'API dataset n'est pas implémentée de façon universelle mais il est aisé de concevoir des alternatives en JavaScript. L'accès aux attributs, quels qu'ils soient, est déjà prévu, donc il suffit de s'adresser spécifiquement à ceux débutant par data- avec les fonctions natives getAttribute et setAttribute qui fonctionnent sur la majorité des navigateurs.

<img src="mamoto.jpg" alt="Une moto rouge" id="moto"
  data-auteur="Simon" data-lieu="Strasbourg"
  data-materiel="EOS" data-gps="48.582967,7.74828">

<script>
var monelement = document.getElementById('moto');

// Lecture d'une valeur
var lieu = monelement.getAttribute('data-lieu');

// Modification d'une valeur
monelement.setAttribute('data-materiel') = 'iOS';

// Suppression
monelement.removeAttribute('data-materiel');
</script>

Du côté de jQuery

La bibliothèque jQuery est équipée de la méthode data() pour accéder à ces données ou les créer, avec quelques différences néanmoins. On omet également le préfixe data- devant les noms des valeurs.

// Lire
$("#moto").data("lieu");

// Modifier la valeur associée
$("#moto").data("lieu","Strasbourg");

// Modifier l'attribut
$("#moto").attr("data-lieu","Strasbourg");

Ces méthodes sont supportées pour tous les navigateurs officiellement pris en charge par jQuery, c'est-à-dire au minimum Internet Explorer 6+. Des plug-ins spécifiques existent avec des fonctions plus complètes, notamment jquery.dataset.js.

Prise en charge (dataset)

Navigateurs Versions
Internet Explorer Internet Explorer 10+ (partiel)
Firefox Firefox 6+
Chrome Chrome 7+
Safari Safari 5.1+
Opera Opera 11.1+

 

Commentaires

A noter qu'avec jQuery, ça fonctionne parfaitement sur IE6+ (émulation avec des tableaux de données JS).

Je ne peux simplement plus m'en passer, par exemples pour les animations JS : on détermine un point de départ et un point d'arrivée dans des attributs data-*, et ça fonctionne tout seul :) Probablement la meilleure innovation de HTML5 à mes yeux.

Merci pour cet article.
Je sais que ce n'est qu'un exemple, mais dans le cas d'une image, n'est ce pas redondant d'ajouter des informations qui sont peut-être déjà présentes dans les métadonnées de l'image elle-même?

Quel bonheur pour créer un plugin jQuery et faire passer ses options via des data-xyz au lieu de devoir les déclarer en JS : on peut faire le plugin auto-exécutable et l'intégrateur HTML avec peu de connaissance du code pourra plus facilement configurer les options.
D'ailleurs, c'est une méthode que propose le bootstrap Twitter.

Oui les data- doivent resté pour un usage interne a l'application.
L'usage des microformats est vite lourd il est vrai que de détourner le champ data- pour y mettre des données et tentant ca donnerait quelques choses comme :

<figure id="photo">
<img src="mamoto.jpg" data-materiel="EOS" alt="Une moto rouge" id="moto" />
<figcaption>
<div itemscope itemtype="http://schema.org/Person">
Photo prise par
<span itemprop="name">Simon</span>
<span itemprop="jobTitle">Photographe</span>
<div itemprop="address" itemscope itemtype="http://schema.org/PostalAddress">
<span itemprop="addressLocality">Strasbourg</span>,
</div>
<div itemprop="geo" itemscope itemtype="http://schema.org/GeoCoordinates">
<meta itemprop="latitude" content="48.582967" />
<meta itemprop="longitude" content="7.74828" />
</div>
</div>
</figcaption>
</figure>

En plus d’être verbeux les microformats sont beaucoup plus dure (plus long) a retravailler en javascript mais comment avoir quelques chose qui puissent être interprété par les moteur notamment pour le référencement et qui puissent être également facile a retravailler? Une astuce?

eh ben ... un Simon-K très actif cette nouvelle année ... on voit bien que le pneu arrière fume encore ... des articles très intéressants et tout chauds ...

@Vincent_ : Effectivement SImon-K carbure au jus de Kiwi...
@Koudelka : Où tu as vu dans l'article que les data jquery = data HTML5, l'article précise bien "avec quelques différences" sur ce point.

J'essaie le moins possible d'utiliser JavaScript, d'une pour des raisons d'accessibilité (quand ce que l'on me demande me permet de ne pas y remédier), de deux parce que je ne suis pas très à l'aise dans ce langage (et oui, il y en a encore qui ont du mal avec ce langage ancestral !!!) mais il faut bien dire qu'avec HTML5, il faudra bien se résoudre à l'utiliser davantage, tout est fait pour simplifier son incorporation/utilisation... Vraiment chouette cette possibilité de définir des données JS dans les balises, à retenir...
Petite coquille dans le paragraphe "Syntaxe" :
"Il bien sûr autorisé de cumuler plusieurs attributs data- sur un même élément."
(manque "est") ;)

Coucou,

Le setAttribute se fait avec 2 paramètres (et non pas une affectation avec un =) :

element.setAttribute("class", "democlass");

J'en profite pour le signaler vu que mon code vient de planter pour ça :P

Bisous