El Atributo ONOFFLINE

Es un evento que se dispara cuando el navegador detecta que se ha perdido la conexión a internet.

El atributo onoffline es un evento que se dispara cuando el navegador detecta que se ha perdido la conexión a internet. Es parte de la API de Online/Offline Events y es esencial para:

  • Mostrar notificaciones de estado

  • Habilitar modos offline

  • Gestionar colas de acciones pendientes

  • Mejorar la experiencia del usuario sin conexión

Sintaxis Básica

HTML:

<body onoffline="miFuncion()">

JavaScript:

window.addEventListener('offline', miFuncion);

Ejemplos Clave

Ejemplo 1: Indicador de Estado Básico

JavaScript:

function manejarOffline() {
    console.log("¡Se perdió la conexión!");
    document.body.style.backgroundColor = "#ffe6e6";
}

Ejemplo 2: Sistema de Cola Offline

JavaScript:

let cola = [];

function agregarAccion() {
    if(!navigator.onLine) {
        cola.push(accion);
        mostrarNotificacion("Acción guardada localmente");
    } else {
        enviarAlServidor(accion);
    }
}

Ejemplo 3: Contenido Caché

HTML:

<div id="contenido-offline" style="display: none;">
    <h2>Modo Offline</h2>
    <p>Contenido disponible sin conexión</p>
</div>

<script>
function manejarOffline() {
    document.getElementById('contenido-offline').style.display = 'block';
}
</script>

Mejores Prácticas

Combina con ononline:

JavaScript:

window.addEventListener('online', sincronizarDatos);

Verifica el estado inicial:

JavaScript:

if(!navigator.onLine) manejarOffline();

Usa notificaciones no intrusivas:

CSS:

.notificacion-offline {
    position: fixed;
    bottom: 20px;
    right: 20px;
    animation: fadeIn 0.5s;
}

Simula estados offline:

  • Chrome DevTools: Network > Offline

  • Firefox: Debugger > Service Workers > Offline

Casos de Uso Avanzados

  • Sincronización diferida: Almacenar localmente formularios enviados

  • Juegos offline: Guardar progreso localmente

  • Lectura offline: Cachear artículos recientes

  • Edición local: Permitir modificar documentos sin conexión

Compatibilidad

Navegador Soporte
Chrome ✅ 4+
Firefox ✅ 3.5+
Safari ✅ 5+
Edge ✅ 12+

Nota importante: Algunos navegadores pueden no detectar correctamente cambios en conexiones WiFi/LAN. Siempre verifica con navigator.onLine.

Consideraciones Especiales

  • Service Workers: Para una verdadera experiencia offline, combina con Service Workers

  • Persistencia de datos: Usa localStorage o IndexedDB para almacenamiento

  • Timeout de detección: Algunas redes pueden reportar falso positivo (ej: conexión a router sin internet)

Conclusión

El atributo onoffline es fundamental para construir aplicaciones web resilientes. Al implementar estrategias offline-first y combinar con tecnologías modernas como Service Workers, puedes crear experiencias que funcionen perfectamente en cualquier condición de red.

HTML:

<!-- Ejemplo Final: Notificación inteligente -->
<div id="offline-alert" aria-live="polite" role="alert">
    <p>Estás trabajando sin conexión. Los cambios se guardarán localmente.</p>
    <button onclick="recargarPagina()">Reintentar conexión</button>
</div>

<script>
function recargarPagina() {
    if(navigator.onLine) {
        location.reload();
    }
}
</script>

Este tutorial te proporciona las bases para implementar detección offline en tus proyectos web. ¡Experimenta y mejora la experiencia de tus usuarios en cualquier situación!

HTML:

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <title>Tutorial: Uso del atributo "onoffline" en HTML</title>
    <style>
        .status-indicator {
            padding: 15px;
            margin: 20px;
            border-radius: 5px;
            display: none;
            position: fixed;
            top: 20px;
            right: 20px;
        }
        .offline {
            background-color: #e74c3c;
            color: white;
        }
        .online {
            background-color: #2ecc71;
            color: white;
        }
        .queue-list {
            border: 2px solid #3498db;
            padding: 15px;
            margin: 20px;
            min-height: 100px;
        }
    </style>
</head>
<body onoffline="manejarOffline()" ononline="manejarOnline()">
    <h1>Tutorial del atributo <code>onoffline</code></h1>

    <!-- Indicador de estado -->
    <div id="status" class="status-indicator">
        Estado de conexión: <span id="status-text">...</span>
    </div>

    <!-- Ejemplo 1: Sistema básico de notificación -->
    <h2>1. Detección básica de conexión</h2>
    <p id="connection-status">Comprobando estado de conexión...</p>

    <!-- Ejemplo 2: Cola de acciones offline -->
    <h2>2. Sistema de cola offline</h2>
    <div class="queue-list">
        <button onclick="agregarAccion()">Agregar acción (+)</button>
        <div id="action-queue"></div>
    </div>

    <!-- Ejemplo 3: Modo lectura offline -->
    <h2>3. Contenido disponible offline</h2>
    <div id="offline-content" style="display: none;">
        <h3>Modo offline activado</h3>
        <p>Contenido disponible sin conexión:</p>
        <ul id="cached-data"></ul>
    </div>

    <script>
        // Detectar estado inicial
        function actualizarEstado() {
            const statusElement = document.getElementById('connection-status');
            statusElement.textContent = navigator.onLine
                ? "✅ Estás conectado a internet"
                : "⚠️ Estás trabajando offline";
        }

        // Manejar eventos de conexión
        function manejarOffline() {
            document.getElementById('status').className = 'status-indicator offline';
            document.getElementById('status-text').textContent = 'Offline';
            document.getElementById('status').style.display = 'block';
            
            // Mostrar contenido offline
            document.getElementById('offline-content').style.display = 'block';
        }

        function manejarOnline() {
            document.getElementById('status').className = 'status-indicator online';
            document.getElementById('status-text').textContent = 'Online';
            document.getElementById('status').style.display = 'block';
            
            // Ocultar contenido offline después de 3 segundos
            setTimeout(() => {
                document.getElementById('status').style.display = 'none';
                document.getElementById('offline-content').style.display = 'none';
            }, 3000);
            
            // Sincronizar cola de acciones
            sincronizarCola();
        }

        // Sistema de cola de acciones
        let acciones = [];
        
        function agregarAccion() {
            if(!navigator.onLine) {
                acciones.push(`Acción ${acciones.length + 1}`);
                actualizarCola();
            } else {
                // Enviar acción inmediatamente si hay conexión
                enviarAccionServidor(`Acción ${acciones.length + 1}`);
            }
        }

        function actualizarCola() {
            document.getElementById('action-queue').innerHTML = acciones
                .map(accion => `<div>${accion} ⌛</div>`)
                .join('');
        }

        function sincronizarCola() {
            if(acciones.length > 0 && navigator.onLine) {
                acciones.forEach(accion => enviarAccionServidor(accion));
                acciones = [];
                actualizarCola();
            }
        }

        function enviarAccionServidor(accion) {
            // Simular envío al servidor
            console.log(`Enviando: ${accion}`);
        }

        // Inicialización
        window.addEventListener('load', () => {
            actualizarEstado();
            if(!navigator.onLine) manejarOffline();
            
            // Cachear datos iniciales
            document.getElementById('cached-data').innerHTML = `
                <li>Documentación importante</li>
                <li>Datos recientes</li>
                <li>Configuración local</li>
            `;
        });

        // Método alternativo usando addEventListener
        window.addEventListener('offline', manejarOffline);
        window.addEventListener('online', manejarOnline);
    </script>
</body>
</html>