Saltar al contenido

Elementos interactivos y widgets en el desarrollo web

Crear widgets personalizados y aprovechar las APIs de HTML puede mejorar significativamente la interactividad y la experiencia de usuario de tus aplicaciones web. Esta guía proporciona instrucciones paso a paso para construir elementos interactivos personalizados como controles deslizantes, modales y pestañas, y te introduce a las APIs de HTML5 como la API de Canvas para crear gráficos dinámicos.

Introducción

Los elementos interactivos y los widgets son componentes esenciales de las aplicaciones web modernas. Mejoran la participación del usuario al proporcionar interfaces dinámicas e interactivas. Esta guía cubre la creación de widgets personalizados y el uso de APIs de HTML5 para construir aplicaciones web responsivas y fáciles de usar.

Mejores prácticas

  1. Usa HTML semántico: Asegúrate de que tu estructura HTML sea significativa y accesible.
  2. Separa las responsabilidades: Mantén HTML, CSS y JavaScript separados para mantener un código limpio y manejable.
  3. Accesibilidad: Asegúrate de que los elementos interactivos sean accesibles para todos los usuarios, incluidos aquellos que usan lectores de pantalla.
  4. Optimización del rendimiento: Minimiza la manipulación del DOM y optimiza JavaScript para garantizar interacciones fluidas.
  5. Diseño responsivo: Asegúrate de que los elementos interactivos funcionen bien en diferentes tamaños de pantalla y dispositivos.

Creación de widgets personalizados

Nota: Para aplicaciones en producción, considera usar elementos nativos de HTML como <code><dialog></code> para modales o <code><details></code> y <code><summary></code> para contenido colapsable antes de construir widgets personalizados.

Control deslizante personalizado

Un control deslizante personalizado permite a los usuarios seleccionar un valor dentro de un rango. A continuación, te mostramos cómo crear uno utilizando HTML, CSS y JavaScript.

Ejemplo

html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Custom Slider</title>
    <style>
        .slider-container {
            display: flex;
            align-items: center;
            gap: 10px;
        }

        #slider {
            width: 200px;
        }
    </style>
</head>
<body>
    <div class="slider-container">
        <input type="range" id="slider" min="0" max="100" value="50" aria-label="Value slider" aria-describedby="slider-value" />
        <span id="slider-value">50</span>
    </div>
    <script>
        document.getElementById('slider').addEventListener('input', function() {
            document.getElementById('slider-value').textContent = this.value;
        });
    </script>
</body>
</html>

Este ejemplo crea un control deslizante simple con un rango de entrada y un elemento span para mostrar el valor actual. JavaScript actualiza el contenido de texto del span a medida que se mueve el control deslizante.

Los modales se utilizan para mostrar contenido en una superposición. A continuación, te mostramos cómo crear un modal personalizado.

Ejemplo

html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Custom Modal</title>
    <style>
        .modal {
            display: none;
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background-color: rgba(0, 0, 0, 0.5);
            justify-content: center;
            align-items: center;
        }

        .modal-content {
            background-color: #fff;
            padding: 20px;
            border-radius: 5px;
            text-align: center;
        }

        .close {
            position: absolute;
            top: 10px;
            right: 10px;
            font-size: 20px;
            cursor: pointer;
        }
    </style>
</head>
<body>
    <button id="open-modal">Open Modal</button>
    <div id="modal" class="modal" role="dialog" aria-modal="true" aria-labelledby="modal-title" tabindex="-1">
        <div class="modal-content">
            <span id="close-modal" class="close" aria-label="Close modal">&times;</span>
            <h2 id="modal-title">Custom Modal</h2>
            <p>This is a custom modal!</p>
        </div>
    </div>
    <script>
        const modal = document.getElementById('modal');
        const openBtn = document.getElementById('open-modal');
        const closeBtn = document.getElementById('close-modal');

        openBtn.addEventListener('click', () => {
            modal.style.display = 'flex';
            closeBtn.focus();
        });

        closeBtn.addEventListener('click', () => {
            modal.style.display = 'none';
            openBtn.focus();
        });

        window.addEventListener('keydown', (e) => {
            if (modal.style.display === 'flex' && e.key === 'Escape') {
                modal.style.display = 'none';
                openBtn.focus();
            }
        });

        modal.addEventListener('click', (event) => {
            if (event.target === modal) {
                modal.style.display = 'none';
                openBtn.focus();
            }
        });
    </script>
</body>
</html>

Este ejemplo demuestra cómo crear un modal que se puede abrir y cerrar con JavaScript. El modal muestra una superposición y un cuadro de contenido, que se puede cerrar haciendo clic en un botón, presionando Escape o haciendo clic en la superposición. El enfoque se gestiona para garantizar que los usuarios de teclado puedan navegar por el diálogo.

Pestañas personalizadas

Las pestañas permiten a los usuarios cambiar entre diferentes secciones de contenido. A continuación, te mostramos cómo crear pestañas personalizadas.

Ejemplo

html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Custom Tabs</title>
    <style>
        .tabs {
            display: flex;
            gap: 10px;
        }

        .tab-button {
            padding: 10px 20px;
            cursor: pointer;
            background-color: #f0f0f0;
            border: 1px solid #ccc;
            border-radius: 5px;
        }

        .tab-button.active {
            background-color: #fff;
            border-bottom: 2px solid #000;
        }

        .tab-content {
            display: none;
            margin-top: 20px;
        }

        .tab-content.active {
            display: block;
        }
    </style>
</head>
<body>
    <div class="tabs" role="tablist">
        <button class="tab-button active" role="tab" aria-selected="true" data-tab="tab1">Tab 1</button>
        <button class="tab-button" role="tab" aria-selected="false" data-tab="tab2">Tab 2</button>
        <button class="tab-button" role="tab" aria-selected="false" data-tab="tab3">Tab 3</button>
    </div>
    <div class="tab-content active" role="tabpanel" aria-labelledby="tab1">
        <p>Content for Tab 1</p>
    </div>
    <div class="tab-content" role="tabpanel" aria-labelledby="tab2">
        <p>Content for Tab 2</p>
    </div>
    <div class="tab-content" role="tabpanel" aria-labelledby="tab3">
        <p>Content for Tab 3</p>
    </div>
    <script>
        const buttons = document.querySelectorAll('.tab-button');
        const contents = document.querySelectorAll('.tab-content');

        function activateTab(clickedBtn) {
            buttons.forEach(btn => {
                btn.classList.remove('active');
                btn.setAttribute('aria-selected', 'false');
            });
            contents.forEach(content => content.classList.remove('active'));

            clickedBtn.classList.add('active');
            clickedBtn.setAttribute('aria-selected', 'true');
            document.getElementById(clickedBtn.dataset.tab).classList.add('active');
        }

        buttons.forEach(button => {
            button.addEventListener('click', () => activateTab(button));
            button.addEventListener('keydown', (e) => {
                let nextIndex;
                if (e.key === 'ArrowRight') nextIndex = (buttons.indexOf(button) + 1) % buttons.length;
                else if (e.key === 'ArrowLeft') nextIndex = (buttons.indexOf(button) - 1 + buttons.length) % buttons.length;
                else return;
                e.preventDefault();
                buttons[nextIndex].focus();
                activateTab(buttons[nextIndex]);
            });
        });
    </script>
</body>
</html>

Este ejemplo crea una interfaz con pestañas. Hacer clic en un botón de pestaña o usar las teclas de flecha izquierda/derecha mostrará el contenido correspondiente y ocultará los demás.

Uso de APIs de HTML5

Introducción a las APIs de HTML5

Las APIs de HTML5 proporcionan funciones potentes que mejoran las aplicaciones web. Una de las APIs de HTML5 más versátiles es la API de Canvas, que permite la creación de gráficos dinámicos.

Uso de la API de Canvas

La API de Canvas te permite dibujar gráficos directamente en una página web. A continuación, se muestra un ejemplo básico de cómo usar la API de Canvas.

Ejemplo

html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Canvas API Example</title>
</head>
<body>
    <canvas id="myCanvas" width="400" height="400" style="border:1px solid #000;"></canvas>
    <script>
        const canvas = document.getElementById('myCanvas');
        const ctx = canvas.getContext('2d');

        // Draw a rectangle
        ctx.fillStyle = '#FF0000';
        ctx.fillRect(50, 50, 150, 100);

        // Draw a circle
        ctx.beginPath();
        ctx.arc(200, 200, 40, 0, 2 * Math.PI);
        ctx.fillStyle = '#00FF00';
        ctx.fill();

        // Draw text
        ctx.font = '20px Arial';
        ctx.fillStyle = '#0000FF';
        ctx.fillText('Hello Canvas', 100, 300);
    </script>
</body>
</html>

Este ejemplo demuestra las funciones básicas de dibujo de la API de Canvas, incluido el dibujo de un rectángulo, un círculo y texto en un elemento canvas. Para actualizaciones dinámicas o animaciones, llama repetidamente a las funciones de dibujo dentro de requestAnimationFrame o en los oyentes de eventos.

INFO

Asegúrate siempre de que tus elementos interactivos sean accesibles. Utiliza roles y propiedades ARIA, HTML semántico y garantiza la navegabilidad por teclado para ofrecer una experiencia de usuario inclusiva para todos. Esto no solo mejora la accesibilidad, sino que también optimiza la usabilidad general y el SEO.

Conclusión

La creación de widgets personalizados como controles deslizantes, modales y pestañas, junto con el uso de APIs de HTML5 como la API de Canvas, puede mejorar significativamente la interactividad y la funcionalidad de las aplicaciones web. Siguiendo estas guías paso a paso, puedes construir elementos web atractivos y dinámicos que mejoren la experiencia del usuario.

Práctica

¿Cuáles de las siguientes afirmaciones sobre elementos interactivos y widgets son verdaderas?

¿Te resulta útil?

Vista previa dual-run — compárala con las rutas Symfony en producción.