Atributos data-*

En ocasiones cuando era necesario aportar cierta metadata a nuestros elementos HTML utilizábamos nuestra originalidad y añadíamos a los mismos atributos personalizados en contra de toda especificación :P.

<input id="txtName" type="text" culture="es-ES" property="Name" />

No era una práctica recomendada pero nos facilitaba la vida en muchas ocasiones. Con esta nueva especificación no sólo nos permitirá crear HTML válido sino que nos proporcionará un mecanismo más homogéneo para lidiar con nuestros atributos personalizados.

Atributos data-*

La forma de definir atributos de este tipo no difiere de la anterior mas que añadir a aquellos personalizados el prefijo data-

<input id="txtName" type="text" data-culture="es-ES" data-property="Name" />

De este modo conseguiremos un HTML 5 válido a los ojos de la W3C, pero no sólo eso sino que además tendremos a nuestra disposición la propiedad dataset, la cual recopila todos, y únicamente, nuestros atributos data-* con acceso de lectura y escritura:

(function () {

    var txtName = document.getElementById('txtName');

    console.log(txtName.dataset);
    console.log(txtName.dataset.culture);
    console.log(txtName.dataset.property);

    txtName.dataset.property += &quot; changed!&quot;;
    console.log(txtName.dataset.property);

})();

El resultado de este script para este ejemplo concreto sería el siguiente:
DOMStringMap data-

Para aquellos navegadores que no soportan la propiedad dataset a día de hoy pueden acceder a estos atributos de la forma tradicional con getAttribute()/setAttribute()

(function () {

    var txtName = document.getElementById('txtName');

    if (txtName.dataset) {

        console.log(txtName.dataset);
        console.log(txtName.dataset.culture);
        console.log(txtName.dataset.property);

        txtName.dataset.property += &quot; changed!&quot;;
        console.log(txtName.dataset.property);
    }
    else {
        console.log(txtName.getAttribute('data-culture'));
        console.log(txtName.getAttribute('data-property'));
        txtName.setAttribute('data-property', 'Name changed!');
        console.log(txtName.getAttribute('data-property'));
    }

})();

También podemos hacer uso de JQuery.data() para obtener menor código y mayor compatibilidad.

Simulando a RequireJS y su data-main

Un uso que he simulado estos días es el uso de data-* en las referencias a los scripts (RequireJS lo hace para indicar cual es el archivo de entrada a través del atributo data-main). Como en el caso de RequireJS, es posible que necesitemos un valor dinámico para un script y en algunas ocasiones no queremos tener un archivo adicional que recupere ese valor e invoque al que realmente lo necesita. El ejemplo sería el siguiente:

<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>
    <input id="txtName" type="text" data-culture="es-ES" data-property="Name" />
    <script src="Scripts/script.js"></script>
    <script src="Scripts/scriptWithDatas.js" data-greeting="Hello world 1!"></script>
    <script src="Scripts/scriptWithDataa.js" data-greeting="Hello world 2!"></script>
    <script src="Scripts/scriptWithData.js" data-greeting="Hello world! 3"></script>
    <script src="Scripts/scriptWithDatara.js" data-greeting="Hello world! 4"></script>
    <script src="Scripts/scriptWithDatap.js" data-greeting="Hello world! 5"></script>
</body>
</html>

Lo que me gustaría en este caso es poder hacer uso de data-greeting dentro de mi script, de la misma forma que hace RequireJS con su data-main. Para ello, podríamos empezar con el siguiente código:

(function () {

    var scripts = document.getElementsByTagName(&quot;script&quot;),
    me = scripts[scripts.length - 1];

    alert(me.dataset.greeting);

})();

Obviamente es un simple ejemplo de cómo llegar hasta el archivo en el que nos encontramos y acto seguido recuperar nuestro atributo, el cual deberíamos de compatibilizar con el resto de navegadores.

Espero que haya sido de utilidad 🙂

CanIUse.com dataset & data-* attributes

¡Saludos!