Sélection d'éléments DOM en JavaScript
Apprenez à sélectionner des éléments DOM en JavaScript avec getElementById, querySelector, querySelectorAll, getElementsByClassName, matches et closest — avec des exemples et conseils d'utilisation.
Avant de pouvoir modifier quoi que ce soit sur une page avec JavaScript — mettre à jour du texte, basculer une classe, attacher un gestionnaire de clic — vous devez d'abord trouver l'élément que vous souhaitez. Cet acte de recherche s'appelle sélectionner un élément DOM. Ce chapitre couvre toutes les méthodes dont vous avez besoin, explique ce que chacune retourne et montre quand utiliser laquelle.
Que signifie « sélectionner un élément »
Le Document Object Model (DOM) est la représentation en direct, en forme d'arbre, de votre HTML par le navigateur. Chaque balise devient un objet nœud que vous pouvez lire et modifier depuis JavaScript. La sélection est le processus de localisation d'un ou plusieurs de ces nœuds afin de pouvoir conserver une référence vers eux dans une variable :
const heading = document.querySelector('h1');
// `heading` now points at the real <h1> on the page.Une fois cette référence obtenue, tout le reste — la lecture des attributs et propriétés, la modification des styles, l'ajout de gestionnaires d'événements — s'effectue sur elle.
Les méthodes de sélection se divisent en deux groupes :
- Recherches par ID / classe / balise — rapides, renvoient des collections live (sauf
getElementById). - Recherches par sélecteur CSS (
querySelector,querySelectorAll) — flexibles, acceptent n'importe quel sélecteur CSS, renvoient un résultat statique.
Sélectionner un élément par son ID : getElementById
La façon la plus rapide d'obtenir un seul élément est de passer par son id unique. Cette méthode renvoie l'élément, ou null si aucun élément avec cet ID n'existe.
const element = document.getElementById('example');
element.textContent = 'You selected the element by its ID!';Les ID étant censés être uniques, getElementById renvoie un seul élément (pas une collection) et constitue la recherche la plus directe et la plus performante.
Si aucun élément ne correspond, getElementById renvoie null. Accéder à une propriété sur null lève une TypeError: Cannot read properties of null. Protégez-vous en testant : const el = document.getElementById('maybe'); if (el) { /* ... */ }.
Sélectionner par nom de classe : getElementsByClassName
Cette méthode renvoie une HTMLCollection live de tous les éléments portant la classe donnée. « Live » signifie que la collection se met à jour automatiquement à mesure que le DOM évolue.
const elements = document.getElementsByClassName('example');
Array.from(elements).forEach((element, index) => {
element.textContent = `Element ${index + 1} changed!`;
});Une HTMLCollection ressemble à un array mais n'en est pas un, elle ne possède donc pas forEach/map. Convertissez-la avec Array.from() (ou le spread [...elements]) avant d'utiliser des méthodes de tableau.
Comme la collection est live, parcourir avec for (let i = 0; i < c.length; i++) tout en supprimant des éléments correspondants peut en sauter certains — la longueur diminue sous vos pieds. Prenez un instantané avec Array.from() si vous prévoyez de muter le DOM pendant la boucle.
Sélectionner par nom de balise : getElementsByTagName
Sélectionne tous les éléments portant un nom de balise donné et renvoie une HTMLCollection live.
const paragraphs = document.getElementsByTagName('p');
for (let i = 0; i < paragraphs.length; i++) {
paragraphs[i].style.backgroundColor = 'yellow';
}Passez '*' pour correspondre à tous les éléments de la page. C'est pratique lorsque vous souhaitez opérer sur toutes les balises d'un type, comme mettre en surbrillance tous les paragraphes.
Sélectionner par attribut name : getElementsByName
Renvoie une NodeList live d'éléments partageant le même attribut name. C'est particulièrement utile pour les contrôles de formulaire — par exemple, tous les boutons radio d'un même groupe :
const options = document.getElementsByName('plan');
options.forEach((radio) => {
radio.addEventListener('change', () => {
console.log('Selected plan:', radio.value);
});
});Pour une gestion plus approfondie des formulaires, consultez travailler avec les formulaires dans le DOM.
Sélectionner avec des sélecteurs CSS : querySelector
querySelector renvoie le premier élément correspondant à n'importe quel sélecteur CSS que vous passez, ou null si rien ne correspond. C'est la méthode de sélection d'un seul élément la plus polyvalente.
const element = document.querySelector('.example');
element.style.backgroundColor = 'lightblue';Comme elle accepte la syntaxe complète des sélecteurs CSS, vous pouvez cibler en profondeur : querySelector('nav ul li.active a') trouve le premier lien correspondant sans enchaîner plusieurs appels.
Sélectionner toutes les correspondances : querySelectorAll
Renvoie une NodeList statique de tous les éléments correspondant au sélecteur. Contrairement à getElementsBy..., cet instantané ne se met pas à jour si le DOM change par la suite.
const elements = document.querySelectorAll('.example');
elements.forEach((element, index) => {
element.style.backgroundColor = 'lightgreen';
element.textContent = `Element ${index + 1} highlighted!`;
});Une NodeList possède une vraie méthode forEach, vous pouvez donc l'itérer directement. Pour utiliser map/filter, convertissez-la d'abord avec Array.from(elements).
querySelectorAll renvoie une NodeList statique — elle ne reflétera pas les éléments ajoutés ou supprimés ultérieurement. getElementsByClassName et getElementsByTagName renvoient des HTMLCollection live qui, elles, se mettent à jour. Choisissez la version statique pour un instantané stable, la version live pour que la collection suive le DOM.
Limiter une recherche à un élément
Toutes les méthodes querySelector* et getElementsBy* existent aussi sur des éléments individuels, pas seulement sur document. Les appeler sur un élément restreint la recherche à ses descendants :
const card = document.querySelector('.card');
const title = card.querySelector('.title'); // only inside .cardLimiter la portée accélère les requêtes et évite de faire correspondre accidentellement des éléments ailleurs sur la page.
Tester un élément : matches
matches ne renvoie pas un élément — elle renvoie true/false selon qu'un élément donné correspond ou non à un sélecteur CSS. Elle est idéale dans les gestionnaires d'événements et la délégation d'événements.
const element = document.getElementById('test');
if (element.matches('.example')) {
element.style.color = 'red';
element.textContent = 'Element matches the selector!';
}Remonter dans l'arbre : closest
closest part de l'élément lui-même et remonte à travers ses ancêtres, renvoyant le plus proche qui correspond au sélecteur (ou null). C'est la façon la plus propre de trouver un élément conteneur.
const element = document.getElementById('child');
const parent = element.closest('.outer');
parent.style.border = '2px solid red';matches + closest constituent la colonne vertébrale de la délégation d'événements : attachez un seul écouteur à un conteneur, puis dans le gestionnaire utilisez event.target.closest('.item') pour déterminer quel enfant a réellement été cliqué. En savoir plus dans la gestion des événements dans le DOM.
Combiner des sélecteurs pour un ciblage précis
Les sélecteurs CSS se composent, vous pouvez donc être aussi précis que nécessaire sans code supplémentaire :
const element = document.querySelector('.example.special');
element.style.backgroundColor = 'pink';
element.textContent = 'Special element highlighted!';Ici .example.special correspond à un élément qui possède les deux classes. Vous pouvez enchaîner des combinateurs (>, espace descendant, +, ~), des sélecteurs d'attribut (input[type="email"]) et des pseudo-classes (li:first-child).
Quelle méthode utiliser ?
| Méthode | Renvoie | Live ? | Idéale pour |
|---|---|---|---|
getElementById | élément unique / null | n/a | un élément avec un ID unique connu |
getElementsByClassName | HTMLCollection | live | tous les éléments d'une classe, en suivant le DOM |
getElementsByTagName | HTMLCollection | live | tous les éléments d'une balise |
getElementsByName | NodeList | live | contrôles de formulaire partageant un name |
querySelector | première correspondance / null | n/a | premier élément correspondant à un sélecteur CSS |
querySelectorAll | NodeList | statique | un instantané stable de toutes les correspondances |
matches | boolean | n/a | tester si un élément correspond à un sélecteur |
closest | ancêtre le plus proche / null | n/a | trouver un élément conteneur |
Règles générales :
- Utilisez par défaut
querySelector/querySelectorAll— une API cohérente avec toute la puissance du CSS. - Utilisez
getElementByIdquand vous avez un ID unique et souhaitez la recherche la plus rapide possible. - N'utilisez une collection live (
getElementsBy...) que si vous avez besoin qu'elle suive les changements du DOM ; sinon préférez lequerySelectorAllstatique.
Erreurs courantes
- Résultats
null.getElementById,querySelectoretclosestrenvoient tousnullen l'absence de correspondance. Vérifiez toujours avant d'utiliser le résultat. - Exécution avant que le DOM existe. Si votre script s'exécute dans
<head>avant que les éléments soient analysés, les sélections ne renvoient rien. Placez les scripts à la fin de<body>, utilisezdefer, ou attendezDOMContentLoaded. - Les collections ne sont pas des arrays.
HTMLCollectionne possède pasforEach.NodeListaforEachmais pasmap/filter. Convertissez avecArray.from()en cas de doute.
Conclusion
Sélectionner des éléments est le point d'entrée de toute tâche DOM. Pour la plupart du code, querySelector et querySelectorAll offrent une API flexible et propulsée par CSS ; getElementById reste le choix le plus rapide pour les ID uniques ; et matches / closest permettent une délégation d'événements propre. Une fois que vous pouvez sélectionner des éléments de manière fiable, continuez avec la manipulation du DOM et le parcours du DOM.
Note de performance : toutes ces méthodes sont suffisamment rapides pour les pages typiques. Le coût réel vient de leur exécution répétée dans des boucles serrées — mettez une sélection en cache dans une variable plutôt que de la relancer. Les NodeList statiques de querySelectorAll évitent la gestion de reflow qui maintient à jour les HTMLCollection live.