IronWoods.es

Desarrollo web

Blog / Javascript / DOM: Gestión con data atributos

Hay varias formas de seleccionar elementos de una página al trabajar con JS, la forma más limpia y eficiente sería usar data-attributes.

Métodos para seleccionar nodos

En el pasado se hacia una selección de elementos por ID o usando diferentes atributos, pudiendo includo seleccionar varios nodos:


    <div class="btn-group text-right">
        <button type="button"
            class="btn btn-default mr-2"
            title="No marcar mensaje como leído"
            id="reject-message">
            Cancelar
        </button>
        <button type="button"
            class="btn btn-primary"
            title="Marcar mensaje como leído"
            id="accept-message">
            Aceptar
        </button>
    </div>

Selección de los botones con getElementById:


    <script>
        const acceptButton = document.getElementById('accept-message');
        const rejectButton = document.getElementById('reject-message');
    </script>

Selección de los botones con querySelector e IDs:


    <script>
        const acceptButton = document.querySelector('#accept-message');
        const rejectButton = document.querySelector('#reject-message');
    </script>

Selección de los botones con querySelector y atributos:


    <script>
        const acceptButton = document.querySelector('button[class="btn-primary"]');
        const rejectButton = document.querySelector('button[class="btn-default"]');
    </script>

Selección de ambos botones con querySelectorAll:


    <script>
        const buttons = document.querySelectorAll('.btn-group button');
    </script>

Entonces podemos usar getElementById con elementos que tienen ID, y querySelector o querySelectorAll sobre diferentes elementos, siendo todos estos métodos "válidos" y necesarios en ciertas ocasiones, pero si podemos crear/editar el HTML lo ideal es identificar los elementos con data atributos, ¿por qué?

  • Los IDs deben ser únicos en cada página. Si estamos añadiendo elementos no podremos duplicarlos y usarlos posteriormente como selectores sin añadir complejidad adicional.
  • Los IDs suelen reservarse para accesibilidad aria-labelledby="..." o formularios for="...".
  • Selectores inespecificos como clases pueden dar lugar a selección de elementos incorrecta, estas no deberían usarse para gestionar elementos con javascript. Otros atributos pueden dar identicos resultados.
  • Usar data-* para identificar elementos para su "comportamiento" es: limpio, reutilizable y permiten entender su utilidad.

Data atributos para usos específicos

Además de usar data-* para comportamiento, debemos usarlos de forma consistente segun su propósito unificando los elementos bajo una misma clave:

Para botones y otros elementos accionables data-action="..."


    <div class="...">
        <button type="button"
            class="..."
            data-action="reject-message">
            Cancelar
        </button>
        <button type="button"
            class="..."
            data-action="accept-message">
            Aceptar
        </button>
    </div>

Para elementos a los que nos referimos, p.e. un template data-ref="..."


    <template data-ref="word-ref" class="...">
        ...
    </template>

Para contenedores de elementos data-container="..."


    <div data-container="words-list" class="..."></div>

Para componentes data-component="..."


    <section class="..." data-component="row-buttons">
        ...
    </section>

Data atributos con elementos repetidos

¿Que ocurre con la selección de elementos si se repiten n veces? Por ejemplo, si tenemos una tabla a la que vamos añadiendo filas dinámicamente y cada fila tiene un botón "Eliminar" asociado, ¿cómo gestionamos la activación del botón?

Podemos usar data-index="n" para identificar cada botón de cada fila.


    <div class="...">
        <button type="button"
            class="..."
            data-action="delete-row"
            data-index="0">
            Eliminar
        </button>
    </div>

Ahora en la parte de javascript, se obtienen todos los botones en base a su acción data-action="delete-row" y se identifica el botón concreto con su índice data-index="n"


    <script>
        // Choose the second delete button
        const secondButton
            = document.querySelector('button[data-action="delete-row"][data-index="1"]')
        console.log(secondButton);
    </script>