
Vayamos con un ejemplo básico. Supongamos que queremos asociar un <div> con la información del usuario juan. Podríamos utilizar el atributo rel:
<div id="card" rel="user-juan">
Información del usuario Juan
</div>
Ahora, al trabajar con jаvascript podríamos buscar el div de id="card", obtener el valor del atributo rel y buscar el texto que comience con user-* para obtener el usuario relacionado. A medida que se necesitan más datos asociados, más complejo se vuelve el atributo rel y más difícil se hace su análisis con jаvascript. Por ejemplo:<div id="card" rel="user-juan card-type-summary show-avatar-size-480">
Información del usuario Juan
</div>
Los atributos data
El atributo data-* permite definir datos personalizados ilimitados y asociarlos a un elemento DOM utilizando cualquier nombre en minúsculas con el prefijo data-. El ejemplo anterior quedaría:
<div id="card" data-user="juan" data-card-type="summary" data-show-avatar-size="480">
Información del usuario Juan
</div>
El atributo data-* es ampliamente utilizado y para evitar posibles conflictos, es recomendable que incluyas en el nombre algún tipo de identificador de tu aplicación. Por ejemplo, yo podría utilizar data-cyb-height en lugar de un genético data-height que pueda ser utilizado por otras aplicaciones. El nombre puede incluir _ y : pero no se recomienda que incluya caracteres especiales distintos a [a-z].Además, has de saber que:
- El valor del atributo data-* puede ser cualquier cadena de texto. Puede contener números pero el tipo de datos es string. Por ejemplo, data-age="30" tendría como valor el texto 30, que es diferente al número 30.
- Los atributos data-* son privados del documento HTML. Esto quiere decir que cualquier sistema externo debería ignorarlos, incluyendo motores de búsqueda. Por tanto, no son adecuados para estructurar datos semánticamente, a diferencia de los microdatos como schema.org u otra especificación1.
- El atributo data-* no debería ser utilizado si existe otro atributo o elemento específico para representar un dato. Por ejemplo, datos de fecha y hora deberían ser incluidos en el elemento <time>.
- El atributo data-* no debería utilizarse como selector CSS o cualquier otro propósito de estilo, pues implica importancia directa para el usuario y, por tanto, esos datos deberían representarse de una forma más accesible.
Trabajando con data-* en jаvascript
Con la introducción de data-* en HTML5 también se introdujeron métodos de acceso y modificación desde jаvascript. En concreto, se introdujo el API dataset (no confundir con datalist), aunque se puede trabajar también con getAttribute y setAttribute, métodos que ya existían antes y no son específicos para los atributos data-*.
Dataset API
El API Dataset permite obtener y establecer los valores de los atributos data-* de un forma muy sencilla. Cada elemento del DOM tiene asociada la propiedad dataset, que es un objeto tipo DOMStringMap con todos sus atributos data-*. Por ejemplo, si tomamos el anterior HTML, podríamos acceder al elemento mediante getElementById y acceder a la propiedad dataset del elemento.
Hay que tener en cuenta que el nombre del atributo en el dataset es transformado eliminando el prefijo data- y del restante se eliminan los guiones y el nombre se transforma a formato camelCase. Por ejemplo, tomemos los atributos data-* del ejemplo anterior. Esta es su correspondencia en el dataset:
- data-user → user
- data-card-type → cardType (nota como se elimina el prefijo data- y del restante se eliminan los guiones y se transforma a notación camelCase).
- data-show-avatar-size → showAvatarSize (fíjate aquí también en la notación camelCase).
// Obtenemos un referencia al elemento
var usercard = document.getElementById("card");
// En la propiedad dataset del elemento estarán todos los atributos data-*
var username = usercard.dataset.user;
var cardtype = usercard.dataset.cardType;
var avatarsize = usercard.dataset.showAvatarSize;
Es decir, el usercard.dataset sería el siguiente objeto:{
user: "juan",
cardType: "summary",
showAvatarSize: "480"
}
Modificar el valor de un atributo data-*, por ejemplo cambiar data-card-type a «full», es tan fácil como asignarle el nuevo valor:// Asignamos un nuevo valor al elemento cardType del dataset,
// el cual hacía referencia al atributo data-card-type
usercard.dataset.cardType = "full";
Para eliminar un valor podríamos asignarle el valor null o un string vacío, pero si queremos eliminar realmente el atributo data-* hay que utilizar el operador delete (tras utilizar el operador delete, si intentamos obtener el valor del atributo obtendremos undefined):delete usercard.dataset.cardType;
El dataset API es soportado en todos los navegadores principales pero en IE sólo está disponible desde la versión IE11. Hay algunas bibliotecas js para implementar el dataset API o puedes utilizar algunos de los siguientes métodos.getAttribute, setAttribute y removeAttribute
Con estos tres métodos se puede obtener y establecer el valor de los atributos data-* así como eliminarlos, incluso en navegadores que no soportan el dataset API.
// Obtenemos un referencia al elemento
var usercard = document.getElementById("card");
// Accedemos a los atributos data-*
var username = usercard.getAttribute( "data-user" );
var cardtype = usercard.getAttribute( "data-card-type" );
var avatarsize = usercard.getAttribute( "data-show-avatar-size" );
// Establecer el valor de un atributo data-*
usercard.setAttribute( 'data-card-type', 'full' );
// Eliminar un atributo con removeAttribute, se le asigna el valor null
usercard.removeAttribute( 'data-card-type' );
jQuery .data()
El método .data() de jQuery ofrece una alta compatibilidad entre diversos navegadores y sería el método de elección si utilizas esta biblioteca. Para acceder a los atributos data-* con este método sólo necesitas el nombre del atributo sin el prefijo data-. Es muy importante saber que el método .data() no afecta al DOM, lo que supone una diferencia importante con el dataset API y con los métodos getAttribute, setAttribute y removeAttribute.
// Obtenemos un referencia al elemento
var usercard = $("#card");
// Accedemos a los atributos data-*
var username = usercard.data( "user" );
var cardtype = usercard.data( "card-type" );
var avatarsize = usercard.data( "show-avatar-size" );
// Establecer el valor de un atributo data-*
usercard.data( 'card-type', 'full' );
// En la alerta saldrá el nuevo valor "full"
alert( usercard.data( "card-type" ) );
// removeData elimina un data previamente almacenado con el método .data()
// Como .data no afecta al DOM, tras utilizar removeData el valor vuelve al inicial "summary"
usercard.removeData( 'card-type' );
// En la alerta saldrá el valor inicial "summary"
alert( usercard.data( "card-type" ) );
También se puede acceder a todos los atributos data a la vez:// userdata será un objeto con todos los atributos data-*
var userdata = $("#card").data();
var username = userdata.user;
var cardtype = userdata.cardType;
var avatarsize = userdata.showAvatarSize;
Cómo ventaja adicional, jQuery tratará de convertir los datos almacenados en un atributo data-* al tipo correcto: lógico, integer, objeto, etc. Por ejemplo, en el siguiente código el atributo data-months es un array.<div id="miDiv" data-months="[1, 5, 12]">
</div>
Con dataset API tendríamos que convertir el string a un array mientras que jQuery lo hace automáticamente:var months = $('#miDiv').data( 'months' ); // months = [1, 5, 12]
Referencias
- W3: Embedding custom non-visible data with the data-* attributes
- HTMLElement.dataset
- jQuery API: .data()
Comentarios