Le DOM est la représentation de la page HTML que le navigateur construit pour permettre à JavaScript de la lire et de la modifier. Dès que vous voulez afficher un message, changer un contenu ou réagir à un clic, vous travaillez avec lui. La bonne nouvelle : pour les interactions courantes, JavaScript natif suffit largement.
Cette approche permet de comprendre ce qui se passe réellement dans le navigateur avant d’ajouter un framework. Elle convient particulièrement aux petits sites, aux prototypes et aux fonctionnalités ciblées dans une page existante.
Le DOM relie le HTML au code JavaScript
Lorsque le navigateur charge une page, il transforme ses balises en une structure arborescente composée de nœuds. Un élément section peut contenir un titre, un paragraphe et un bouton ; chacun de ces éléments devient accessible depuis JavaScript.
Le document est le point d’entrée principal. Il représente la page actuellement ouverte et fournit les méthodes nécessaires pour rechercher des éléments, en créer de nouveaux ou écouter les actions de l’utilisateur.
Cette distinction est utile : JavaScript ne modifie pas directement le fichier HTML enregistré sur le serveur. Il modifie la copie du document chargée dans le navigateur. Pour conserver un changement après un rechargement, il faut donc l’enregistrer côté serveur, dans une base de données ou dans un autre mécanisme adapté.
Sélectionner un élément de manière fiable
La méthode la plus polyvalente est querySelector. Elle accepte un sélecteur CSS et renvoie le premier élément correspondant. Vous pouvez donc cibler une classe, un identifiant ou une combinaison de sélecteurs, comme vous le feriez dans une feuille de style.
Pour récupérer tous les éléments correspondants, utilisez querySelectorAll. Le résultat peut ensuite être parcouru pour appliquer la même opération à plusieurs éléments. Par exemple, une page contenant plusieurs boutons portant la classe action peut être traitée avec une seule logique plutôt qu’avec des instructions répétées.
La sélection doit rester suffisamment précise. Un sélecteur trop général risque de modifier des éléments inattendus, tandis qu’un sélecteur dépendant d’une structure HTML fragile cassera plus facilement lorsque la page évoluera.
Vérifiez également qu’un élément existe avant de l’utiliser. Si le script est chargé sur une page qui ne contient pas le sélecteur recherché, une tentative de modification d’une valeur inexistante provoquera une erreur. Cette précaution est particulièrement importante lorsque le même fichier JavaScript est utilisé sur plusieurs pages.
Modifier le contenu sans créer de faille
Pour changer le texte visible d’un élément, privilégiez textContent. Cette propriété traite la valeur comme du texte, même si elle contient des caractères qui ressemblent à des balises HTML. C’est le choix approprié pour afficher un nom, un résultat de calcul ou un message fourni par un utilisateur.
innerHTML peut insérer du HTML, mais son usage demande davantage de contrôle. Injecter directement une donnée externe ou saisie par un visiteur peut créer une faille XSS, car le navigateur pourrait interpréter une partie de cette donnée comme du code. Pour un simple contenu textuel, innerHTML n’apporte donc aucun avantage.
Vous pouvez aussi modifier des attributs avec setAttribute, ou utiliser directement les propriétés prévues par le navigateur pour certains cas courants. Pour une image, par exemple, changer sa source et son texte alternatif ne se résume pas à modifier le texte affiché : les deux attributs doivent rester cohérents avec le contenu proposé.
Réagir aux actions avec addEventListener
Une page interactive attend des événements : clic sur un bouton, saisie dans un champ, envoi d’un formulaire ou déplacement de la souris. La méthode addEventListener permet d’associer une fonction à l’un de ces événements sans mélanger le comportement avec le balisage HTML.
Le principe est simple : vous sélectionnez l’élément, vous indiquez le type d’événement, puis vous fournissez la fonction à exécuter. Pour un bouton, l’événement click est le plus courant. Pour un champ, input permet de réagir au fur et à mesure de la saisie, tandis que change intervient généralement lorsque la valeur est modifiée puis validée ou perd le focus.
L’objet événement transmis à la fonction contient des informations utiles, notamment l’élément à l’origine de l’action. Il permet aussi de contrôler le comportement par défaut. Dans le cas d’un formulaire, preventDefault évite l’envoi immédiat de la page lorsque vous souhaitez d’abord vérifier les données côté navigateur.
Un exemple de logique pour un bouton
Imaginez un bouton « Afficher les détails » et une zone masquée. Au clic, le script sélectionne la zone, vérifie son état, puis ajoute ou retire une classe CSS. Le JavaScript décide du changement d’état ; la feuille de style décide de l’apparence associée. Cette séparation rend le comportement plus lisible et évite de multiplier les styles directement depuis le script.
Un bouton accessible doit aussi refléter son état. Si son action ouvre ou ferme une zone, l’attribut aria-expanded peut être mis à jour en même temps que la classe visuelle. L’utilisateur ne doit pas dépendre uniquement d’une animation ou d’un changement de couleur pour comprendre ce qui vient de se produire.
Modifier les classes plutôt que les styles ligne par ligne
La propriété classList fournit des méthodes adaptées aux états d’interface : add pour ajouter une classe, remove pour la supprimer et toggle pour alterner entre les deux. Cette méthode est généralement préférable à la modification répétée de style, car les règles d’apparence restent regroupées dans le fichier CSS.
Une classe peut représenter un état comme ouvert, actif, erreur ou chargement. Le script se contente alors de signaler l’état, tandis que CSS gère la visibilité, la couleur, l’espacement et les transitions. Cette organisation simplifie aussi la maintenance lorsque le design change.
Évitez toutefois d’utiliser une classe uniquement pour cacher un contenu important aux technologies d’assistance. Une zone masquée visuellement doit conserver un comportement cohérent pour les personnes qui naviguent au clavier ou utilisent un lecteur d’écran.
Créer et supprimer des éléments dynamiquement
JavaScript peut construire un élément avec document.createElement, lui attribuer un texte ou des propriétés, puis l’ajouter dans la page avec append ou appendChild. Cette technique convient à une liste filtrée, à un message de confirmation ou à une série de résultats dont le nombre n’est pas connu à l’avance.
Pour une liste de tâches, une stratégie sûre consiste à créer chaque élément séparément, à placer le libellé avec textContent, puis à l’insérer dans le conteneur. Vous évitez ainsi de concaténer des chaînes HTML contenant des données utilisateur.
Pour retirer un élément, remove suffit dans les navigateurs modernes. Avant toute suppression, prévoyez une confirmation lorsque l’action est irréversible ou difficile à annuler. Une interface rapide n’est pas forcément une interface claire.
Éviter les problèmes fréquents
Les erreurs liées au DOM proviennent souvent moins de la syntaxe que du moment où le script s’exécute. Si JavaScript cherche un élément avant que le navigateur ait chargé le HTML correspondant, la sélection peut échouer. Placez le script en fin de document ou utilisez une stratégie de chargement qui garantit que le balisage est disponible avant l’exécution.
- Élément introuvable : vérifiez le sélecteur, la casse et la page concernée.
- Événement non déclenché : assurez-vous que l’écouteur est attaché au bon élément.
- Valeur inattendue : contrôlez le contenu d’un champ avant de l’utiliser.
- Modification trop large : préférez un sélecteur ciblé à une sélection globale.
- Interface incohérente : mettez à jour en même temps le contenu, l’état visuel et les attributs d’accessibilité.
Les outils de développement du navigateur facilitent le diagnostic. La console permet de repérer les erreurs JavaScript, tandis que l’inspecteur montre la structure actuelle du DOM et les classes réellement appliquées. Testez aussi les interactions au clavier et sur un écran étroit : une fonctionnalité qui fonctionne uniquement au clic n’est pas complète.
Une méthode simple pour construire une interaction
- Définissez l’état initial : que voit l’utilisateur avant toute action ?
- Identifiez le déclencheur : clic, saisie, envoi ou changement de sélection.
- Sélectionnez les éléments concernés : bouton, zone à modifier et éventuel message d’erreur.
- Décrivez la transition : contenu à changer, classe à ajouter ou élément à créer.
- Gérez les cas limites : champ vide, double clic, élément absent ou résultat indisponible.
- Testez l’accessibilité : clavier, focus, libellés et annonce des changements importants.
Commencer par cette séquence évite de produire un script qui réagit correctement dans un seul scénario. Le code devient une traduction d’un comportement défini, plutôt qu’un ensemble de modifications ajoutées au hasard.
JavaScript natif offre déjà les bases nécessaires pour sélectionner, modifier et faire vivre une page. Une bibliothèque ou un framework peut devenir pertinent lorsque l’interface est très riche, que l’état est partagé entre de nombreux composants ou que l’équipe a besoin d’une architecture standardisée. Pour une interaction isolée, comprendre le DOM et utiliser les API du navigateur reste souvent la solution la plus légère et la plus facile à maintenir.