Cómo usar atributos de datos HTML con JavaScript y CSS

Cómo pasar e interactuar con datos misceláneos pasados ​​a elementos HTML a través de atributos de datos.

Para este tutorial, vamos a utilizar el marco JavaScript de pila completa de CheatCode, Joystick. Joystick reúne un marco de interfaz de usuario de front-end con un back-end de Node.js para crear aplicaciones.

Para comenzar, querremos instalar Joystick a través de NPM. Asegúrese de estar usando Node.js 16+ antes de instalar para garantizar la compatibilidad (lea este tutorial primero si necesita aprender a instalar Node.js o ejecutar varias versiones en su computadora):

Terminal

npm i -g @joystick.js/cli

Esto instalará Joystick globalmente en su computadora. Una vez instalado, vamos a crear un nuevo proyecto:

Terminal

joystick create app

Después de unos segundos, verá un mensaje desconectado en cd en su nuevo proyecto y ejecute joystick start :

Terminal

cd app && joystick start

Después de esto, su aplicación debería estar ejecutándose y estamos listos para comenzar.

Agregar atributos de datos a los elementos

Para comenzar, vamos a modificar el archivo existente en /ui/pages/index/index.js en nuestra aplicación para darnos una pizarra en blanco con la que trabajar (esto ya está conectado a la ruta raíz en http://localhost:2600/ lo que facilitará la prueba de nuestro trabajo):

/ui/pages/index/index.js

import ui from '@joystick.js/ui';

const Index = ui.component({
  render: () => {
    return `
      <div>
      </div>
    `;
  },
});

export default Index;

Aquí, solo estamos reemplazando el código existente con un componente Joystick barebones. Esto nos da un <div></div> vacío etiqueta en el navegador y nada más (si cargamos http://localhost:2600 en el navegador ahora, no veremos nada que sea correcto).

A partir de aquí, actualicemos nuestro HTML para incluir algunas etiquetas adicionales con atributos de datos y explicar lo que está sucediendo:

/ui/pages/index/index.js

import ui from '@joystick.js/ui';

const Index = ui.component({
  render: () => {
    return `
      <div>
        <div class="text" data-story="He huffed, and he puffed, and blew the house down."></div>
        <div class="icon" magic="🥳"></div>
      </div>
    `;
  },
});

export default Index;

Casi idéntico, pero dentro de nuestro <div></div> vacío etiqueta, hemos agregado dos divs adicionales. Al primero se le da una clase de text y al segundo se le da una clase de icon .

En el text div, hemos agregado un atributo de datos data-story con un valor establecido en una cadena que cuenta una historia corta. Aquí, data-story es un atributo HTML no estándar. Podemos salirnos con la nuestra porque estamos usando el data- prefijo que le dice a HTML que se trata de un atributo de datos personalizado.

En el icon div, hemos agregado un atributo magic al que se le asigna un valor de 🥳, o el emoji de "cara de fiesta". Aunque nuestro enfoque en este tutorial está en los atributos de los datos, vale la pena señalarlo. Técnicamente hablando, puede agregar cualquier atributo personalizado a una etiqueta HTML (por ejemplo, pizza="🍕" ) y el uso que veremos más adelante seguirá funcionando, sin embargo, el peligro con esto es que podría tener conflictos con real o atributos HTML admitidos. Si bien la mayoría de los navegadores respetarán esto, puede tener consecuencias sorprendentes (como ser identificado/omitido por un linter HTML).

Estamos haciendo esto aquí como un ejemplo, pero la recomendación es anteponer cualquier nombre de atributo personalizado con data- .

Recuperación y manipulación de atributos de datos

En este punto, el trabajo que hemos realizado puede parecer bastante inútil más allá de agregar algunos metadatos adicionales a nuestro HTML. Para que esto sea más útil, echemos un vistazo a cómo recuperar y manipular atributos de datos agregando algunos detectores de eventos DOM a nuestro HTML:

/ui/pages/index/index.js

import ui from '@joystick.js/ui';

const Index = ui.component({
  events: {
    'click [data-story]': (event) => {
      const story = event.target.getAttribute('data-story');
      event.target.setAttribute('data-story', story?.split('').reverse().join(''));
    },
    'click [magic]': () => {
      alert('It\'s an emoji, maaaan.');
    },
  },
  render: () => {
    return `
      <div>
        <div class="text" data-story="He huffed, and he puffed, and blew the house down."></div>
        <div class="icon" magic="🥳"></div>
      </div>
    `;
  },
});

export default Index;

Aquí, estamos haciendo uso de la capacidad de un componente Joystick para agregar detectores de eventos DOM a los elementos representados por nuestro componente. Aquí, hemos agregado un click detector de eventos para el [data-story] selector. Esto puede parecer un poco extraño. Por lo general, un selector de eventos (o selector de CSS, si lo prefiere, los nombres a menudo se usan indistintamente) es un .class-like-this o un #id-like-this .

Aquí, estamos seleccionando un elemento por su atributo HTML. Para hacerlo, envolvemos el nombre del atributo entre corchetes [] . Tenga en cuenta que no especificamos el valor del atributo, solo el nombre del atributo (la parte antes del = en nuestro HTML).

El comportamiento aquí es idéntico al que esperaría con una clase o una ID; simplemente estamos usando un atributo diferente para "apuntar" o "encontrar" el elemento en el DOM. Una vez que lo tenemos, a nuestra definición de oyente click [data-story] , pasamos una función que será llamada cuando click el evento se detecta en elementos con un data-story atributo.

Dentro de esa función, tomamos el DOM event que fue capturado por el oyente y primero, recuperar el valor actual de nuestro atributo de datos (almacenando el valor en una variable story ) llamando al .getAttribute() método que es accesible en todos los elementos DOM. Aquí, event.target representa el elemento en el que se detectó el evento. A .getAttribute() , pasamos el nombre del atributo para el que queremos recuperar el valor.

Para demostrar lo contrario de esto, establecer un atributo en un elemento a través de JavaScript, en la línea debajo de esto, usamos nuevamente el event.target valor, pero esta vez llama a .setAttribute() , pasando dos argumentos:el nombre del atributo que queremos establecer seguido del valor que queremos establecer.

Para divertirnos un poco, tomamos el story variable (el valor original de nuestro atributo) y use el .split() método para dividir la cadena en una matriz. Luego, llamamos .reverse() en esa matriz resultante seguida de .join('') para unir la matriz de nuevo en una cadena. En caso de que no esté claro, solo estamos invirtiendo el valor de cadena existente de nuestro atributo de datos antes de volver a configurarlo en nuestro <div></div> .

Para asegurarse de que todo esto quede claro, recuerde que anteriormente mencionamos que podemos agregue atributos personalizados sin el data- prefijo (aunque, se debe tener precaución al hacer esto para evitar problemas inesperados). Como insinuamos, mientras que esto debería funciona en la mayoría de los navegadores, no confíe en él. Independientemente, usando el mismo enfoque para nuestro data- atributo, agregamos un click detector de eventos en nuestro [magic] atributo con click [magic] . Se aplican todas las mismas reglas, sin embargo, en lugar de recuperar el valor aquí, simplemente activamos un alert() para demostrar que podemos agregue un oyente a un atributo personalizado.

Si bien eso cubre el caso de uso principal de los atributos de datos, a continuación, veremos una característica menos conocida de los atributos de datos:la capacidad de usarlos en CSS.

Usar atributos de datos en CSS

Hay dos formas de usar atributos de datos (nuevamente, usamos esto como un término "cajón de sastre" para referirnos a cualquier atributo HTML para fomentar el buen comportamiento) en CSS:como selectores, similar a lo que vimos con los selectores de eventos arriba, y como valores en nuestro CSS. Agreguemos algo de CSS que demuestre estas dos técnicas a nuestro componente y luego expliquemos cómo funciona:

/ui/pages/index/index.js

import ui from '@joystick.js/ui';

const Index = ui.component({
  css: `
    [data-story] {
      font-size: 18px;
      font-style: italic;
      color: red;
    }

    [data-story]:before {
      content: attr(data-story);
    }

    .icon:before {
      content: attr(magic);
    }

    [magic] {
      font-size: 80px;
    }
  `,
  events: { ... },
  render: () => {
    return `
      <div>
        <div class="text" data-story="He huffed, and he puffed, and blew the house down."></div>
        <div class="icon" magic="🥳"></div>
      </div>
    `;
  },
});

export default Index;

Comenzando con nuestro data-story <div></div> , en nuestro CSS, usamos el [data-story] selector que vimos anteriormente para seleccionar el <div></div> y luego aplicarle algunos estilos. Suficientemente simple. Sin embargo, donde las cosas se ponen interesantes es con CSS pseudo elementos como :before y :after .

Aquí, usando el mismo [data-story] selector, agregamos un :before propiedad inmediatamente después para decir "queremos agregar estilos para el :before pseudo elemento en elementos con el data-story atributo ". En CSS, un pseudo elemento es, como su nombre lo indica, un elemento que en realidad no existe. En cambio, los pseudo elementos solo existen en la memoria y no en el DOM (aunque en los navegadores modernos, aparecen en los "Elementos " junto con su marcado) pero aún aparecen en la pantalla.

Para definir un pseudo-elemento, necesitamos especificar un content propiedad en nuestras reglas CSS (de lo contrario, el elemento no aparece en la pantalla). Aquí es donde las cosas se ponen interesantes:en CSS, existe una "función" especial llamada attr() que se puede asignar al content propiedad en nuestro CSS. A esa función, podemos pasar el nombre de un atributo HTML del que queremos recuperar el valor, estableciéndolo como el contenido de nuestro pseudo-elemento.

Si omitimos estos estilos, notaremos que nuestro <div></div> permanece vacío en la pantalla. Sin embargo, tan pronto como agreguemos esto, nuestro pseudo :before el elemento se rellena con el contenido recuperado a través de attr() . Al igual que todo lo demás que vimos anteriormente, esto también funciona para los atributos personalizados no con el prefijo data- .

Si abrimos nuestra aplicación en el navegador, deberíamos ver nuestro texto estilizado y emoji en la pantalla. Continúe y haga clic en ellos para ver cómo se aplican nuestros eventos.

Terminando

En este tutorial, aprendimos a usar atributos de datos HTML para agregar datos personalizados a nuestros elementos HTML. Aprendimos la diferencia entre data- elementos con prefijo y elementos sin el data- prefijo. A continuación, aprendimos cómo agregar detectores de eventos DOM de JavaScript, usando atributos de datos personalizados como nuestro selector, aprendiendo cómo modificar los atributos de un elemento sobre la marcha. Finalmente, aprendimos a usar atributos DOM personalizados para diseñar y configurar dinámicamente el contenido de un pseudoelemento CSS a través del attr() función.