Chapitre 6 : HTML5 – APIs avancées

📍 1. API de Géolocalisation

L'API de géolocalisation permet d'obtenir la position géographique de l'utilisateur (avec son autorisation).

📝 Syntaxe de base

// Vérifier si le navigateur supporte la géolocalisation
if ("geolocation" in navigator) {
    navigator.geolocation.getCurrentPosition(successCallback, errorCallback);
} else {
    console.log("Géolocalisation non supportée");
}

function successCallback(position) {
    const lat = position.coords.latitude;
    const lng = position.coords.longitude;
    console.log(`Latitude : ${lat}, Longitude : ${lng}`);
}

function errorCallback(error) {
    switch(error.code) {
        case error.PERMISSION_DENIED: console.log("Permission refusée"); break;
        case error.POSITION_UNAVAILABLE: console.log("Position indisponible"); break;
        case error.TIMEOUT: console.log("Délai dépassé"); break;
    }
}

📌 Options de géolocalisation

enableHighAccuracy

Active la haute précision (GPS) - par défaut false

timeout

Délai maximum (ms) avant erreur - par défaut infini

maximumAge

Âge maximum d'une position mise en cache (ms)

📝 Exemple : Obtenir la position actuelle

navigator.geolocation.getCurrentPosition(
    (position) => {
        document.getElementById('lat').textContent = position.coords.latitude;
        document.getElementById('lng').textContent = position.coords.longitude;
        document.getElementById('accuracy').textContent = position.coords.accuracy;
    },
    (error) => {
        document.getElementById('geo-error').textContent = "Erreur : " + error.message;
    }
);
✨ Démo interactive

📝 Exemple : Suivi de position en temps réel

// watchPosition suit les déplacements
const watchId = navigator.geolocation.watchPosition(
    (position) => {
        // Mise à jour de l'affichage à chaque déplacement
        updatePosition(position);
    },
    (error) => handleError(error),
    { enableHighAccuracy: true }
);

// Pour arrêter le suivi
navigator.geolocation.clearWatch(watchId);
💡 Cas d'usage : Applications météo, services de livraison, cartes interactives, géocaching.

💾 2. Web Storage (Stockage local)

Le Web Storage permet de stocker des données localement dans le navigateur, sans expiration.

❌ Cookies

  • 4 KB max
  • Envoyés à chaque requête HTTP
  • Expiration configurable

Web Storage

  • 5-10 MB max
  • Non envoyés au serveur
  • Persistant jusqu'à effacement

📌 Deux types de stockage

localStorage

Données persistantes même après fermeture du navigateur

localStorage.setItem('key', 'value');
const value = localStorage.getItem('key');
localStorage.removeItem('key');
localStorage.clear();
sessionStorage

Données valides uniquement pendant la session (onglet fermé = perdu)

sessionStorage.setItem('key', 'value');
const value = sessionStorage.getItem('key');
sessionStorage.removeItem('key');
sessionStorage.clear();

📝 Exemple : Thème personnalisé avec localStorage

<select id="theme">
    <option value="clair">Clair</option>
    <option value="sombre">Sombre</option>
</select>

<script>
    // Charger le thème sauvegardé
    const savedTheme = localStorage.getItem('theme') || 'clair';
    document.getElementById('theme').value = savedTheme;
    applyTheme(savedTheme);

    // Sauvegarder le choix
    document.getElementById('theme').addEventListener('change', (e) => {
        localStorage.setItem('theme', e.target.value);
        applyTheme(e.target.value);
    });
</script>
✨ Démo : Sauvegarde de préférences
Ce texte change selon votre thème !

📝 Exemple : Liste de tâches avec localStorage

// Sauvegarder une liste de tâches
let tasks = JSON.parse(localStorage.getItem('tasks')) || [];

function addTask(task) {
    tasks.push(task);
    localStorage.setItem('tasks', JSON.stringify(tasks));
}

function getTasks() {
    return JSON.parse(localStorage.getItem('tasks')) || [];
}

function removeTask(index) {
    tasks.splice(index, 1);
    localStorage.setItem('tasks', JSON.stringify(tasks));
}
✨ Démo : To-Do List persistante

    🖱️ 3. API Drag and Drop

    L'API Drag and Drop permet de rendre les éléments déplaçables et de définir des zones de dépôt.

    📝 Syntaxe de base

    <div draggable="true" ondragstart="dragStart(event)">Élément déplaçable</div>
    <div ondrop="drop(event)" ondragover="allowDrop(event)">Zone de dépôt</div>
    
    <script>
        function dragStart(event) {
            event.dataTransfer.setData("text/plain", event.target.id);
        }
        function allowDrop(event) {
            event.preventDefault();
        }
        function drop(event) {
            event.preventDefault();
            const data = event.dataTransfer.getData("text/plain");
            const draggedElement = document.getElementById(data);
            event.target.appendChild(draggedElement);
        }
    </script>

    📌 Événements Drag and Drop

    dragstart

    Début du glissement

    dragend

    Fin du glissement

    dragover

    Élément survolé (nécessite preventDefault)

    dragenter

    Entrée dans la zone de dépôt

    dragleave

    Sortie de la zone de dépôt

    drop

    Dépose de l'élément

    📝 Exemple : Liste de tâches triable par glisser-déposer

    <ul id="taskList">
        <li draggable="true" ondragstart="dragStart(event)">Tâche 1</li>
        <li draggable="true" ondragstart="dragStart(event)">Tâche 2</li>
    </ul>
    
    <script>
        let dragIndex = null;
        function dragStart(event) {
            dragIndex = event.target;
            event.dataTransfer.setData("text/plain", "move");
        }
        function drop(event) {
            event.preventDefault();
            const targetLi = event.target.closest('li');
            if (targetLi && dragIndex !== targetLi) {
                const parent = dragIndex.parentNode;
                const children = [...parent.children];
                const dragPos = children.indexOf(dragIndex);
                const targetPos = children.indexOf(targetLi);
                if (dragPos < targetPos) {
                    parent.insertBefore(dragIndex, targetLi.nextSibling);
                } else {
                    parent.insertBefore(dragIndex, targetLi);
                }
            }
        }
    </script>
    ✨ Démo : Glissez-déposez les tâches pour les réorganiser
    • 📝 Apprendre HTML5
    • 🎨 Maîtriser CSS3
    • ⚡ JavaScript avancé
    • 🌐 API REST
    • 🗄️ Bases de données

    💡 Essayez de réorganiser les tâches par glisser-déposer !

    💡 Cas d'usage : Organisateurs de tâches, upload de fichiers par glisser-déposer, jeux de puzzle, réorganisation de galeries d'images.

    ⚙️ 4. Web Workers

    Les Web Workers permettent d'exécuter des scripts en arrière-plan, sans bloquer l'interface utilisateur.

    ❌ Sans Worker

    Un calcul long bloque l'interface → Page non responsive

    // Cette boucle bloque tout !
    for(let i = 0; i < 1e10; i++) {
        // calcul intensif
    }

    ✅ Avec Worker

    Le calcul s'exécute en arrière-plan → Interface réactive

    const worker = new Worker('worker.js');
    worker.postMessage('start');
    worker.onmessage = (e) => {
        console.log('Résultat:', e.data);
    };

    📝 Exemple : Création d'un Web Worker

    // worker.js (fichier séparé)
    self.onmessage = function(e) {
        let result = 0;
        for(let i = 0; i < e.data; i++) {
            result += i;
        }
        self.postMessage(result);
    };
    
    // script principal
    if (window.Worker) {
        const myWorker = new Worker('worker.js');
        myWorker.postMessage(1000000000);
        myWorker.onmessage = function(e) {
            console.log('Somme calculée : ' + e.data);
        };
    }

    📝 Exemple démo : Calcul intensif sans bloquer l'interface

    // Fonction worker inline (Blob)
    const workerCode = `
        self.onmessage = function(e) {
            let result = 0;
            for(let i = 0; i < e.data.iterations; i++) {
                result += Math.sqrt(i);
            }
            self.postMessage({ result, iterations: e.data.iterations });
        };
    `;
    const blob = new Blob([workerCode], {type: "application/javascript"});
    const worker = new Worker(URL.createObjectURL(blob));
    
    worker.postMessage({ iterations: 50000000 });
    worker.onmessage = (e) => {
        console.log(`Terminé: ${e.data.result}`);
    };
    ✨ Démo : Calcul intensif en arrière-plan
    ⏳ Prêt
    Clics sur le bouton rouge : 0

    📌 Types de Workers

    Dedicated Worker

    Worker dédié à un script - communication unique

    Shared Worker

    Partagé entre plusieurs scripts / onglets

    Service Worker

    Proxy réseau pour les PWA (caching, notifications offline)

    💡 Cas d'usage : Traitement d'images/vidéos, calculs scientifiques, chiffrement, parsing de gros fichiers JSON.

    🔌 5. WebSockets – Communication temps réel

    Les WebSockets permettent une communication bidirectionnelle en temps réel entre le navigateur et le serveur.

    ❌ HTTP (Polling)

    Requêtes répétitives → Latence + Surcharge

    setInterval(() => {
        fetch('/api/messages').then(...);
    }, 1000);

    ✅ WebSocket

    Connexion permanente → Communication instantanée

    const ws = new WebSocket('ws://server.com');
    ws.onmessage = (event) => {
        // Réception immédiate
    };

    📝 Syntaxe de base (client WebSocket)

    // Connexion WebSocket
    const socket = new WebSocket('wss://echo.websocket.org');
    
    // Ouverture de la connexion
    socket.onopen = () => {
        console.log('Connecté');
        socket.send('Bonjour serveur !');
    };
    
    // Réception de messages
    socket.onmessage = (event) => {
        console.log('Message reçu :', event.data);
    };
    
    // Erreur
    socket.onerror = (error) => {
        console.error('Erreur :', error);
    };
    
    // Fermeture
    socket.onclose = () => {
        console.log('Déconnecté');
    };
    
    // Envoyer un message
    socket.send('Hello world');

    📝 Exemple démo : Chat simple avec WebSocket public

    const ws = new WebSocket('wss://echo.websocket.org');
    
    document.getElementById('sendBtn').onclick = () => {
        const msg = document.getElementById('msgInput').value;
        ws.send(msg);
        addMessage(`Moi: ${msg}`, 'outgoing');
    };
    
    ws.onmessage = (event) => {
        addMessage(`Serveur: ${event.data}`, 'incoming');
    };
    
    function addMessage(msg, type) {
        const div = document.createElement('div');
        div.textContent = msg;
        div.style.padding = '5px 10px';
        div.style.margin = '5px';
        div.style.borderRadius = '15px';
        div.style.backgroundColor = type === 'outgoing' ? '#3498db' : '#ecf0f1';
        div.style.color = type === 'outgoing' ? 'white' : '#333';
        div.style.textAlign = type === 'outgoing' ? 'right' : 'left';
        messagesContainer.appendChild(div);
    }
    ✨ Démo : Communication WebSocket
    🟡 Connexion en cours...

    🔌 Connexion à echo.websocket.org (serveur de test - renvoie le message)

    📌 Événements WebSocket

    onopen

    Connexion établie

    onmessage

    Message reçu

    onerror

    Erreur de connexion

    onclose

    Connexion fermée

    💡 Cas d'usage : Chat en direct, notifications push, jeux multijoueurs, trading en temps réel, collaboration en ligne (Google Docs-like).

    📝 Tableau récapitulatif des APIs HTML5

    API Description Méthodes clés Cas d'usage
    📍 Géolocalisation Position géographique getCurrentPosition(), watchPosition() Météo, cartes, livraison
    💾 Web Storage Stockage local persistant localStorage, sessionStorage Préférences, thèmes, panier
    🖱️ Drag & Drop Glisser-déposer natif dragstart, dragend, drop To-do lists, upload de fichiers
    ⚙️ Web Workers Multithreading JS Worker(), postMessage(), onmessage Calculs intensifs, parsing lourd
    🔌 WebSockets Temps réel bidirectionnel WebSocket(), send(), onmessage Chat, jeux, notifications

    📌 Quiz de vérification

    Question 1 : Quelle méthode utilise-t-on pour obtenir la position actuelle de l'utilisateur ?

    📖 Voir la réponse
    ✅ Réponse

    navigator.geolocation.getCurrentPosition(success, error)

    Question 2 : Quelle est la différence entre localStorage et sessionStorage ?

    📖 Voir la réponse
    ✅ Réponse

    localStorage persiste après fermeture du navigateur, sessionStorage est effacé à la fermeture de l'onglet.

    Question 3 : Quel événement doit-on utiliser pour autoriser un dépôt dans Drag and Drop ?

    📖 Voir la réponse
    ✅ Réponse

    dragover avec event.preventDefault()

    Question 4 : À quoi servent les Web Workers ?

    📖 Voir la réponse
    ✅ Réponse

    Exécuter des scripts en arrière-plan sans bloquer l'interface utilisateur (multithreading).

    Question 5 : Quel protocole utilise WebSocket ?

    📖 Voir la réponse
    ✅ Réponse

    ws:// (non sécurisé) ou wss:// (sécurisé)