JavaScript Recherche : getElement*, querySelector*
Explorez et maîtrisez le DOM JavaScript avec getElement* et querySelector* pour créer des applications web interactives et dynamiques.
Avant de pouvoir modifier, déplacer ou lire quoi que ce soit sur une page, vous devez trouver l'élément souhaité. C'est la toute première étape de presque toutes les opérations DOM, et JavaScript vous offre deux familles d'outils pour cela :
- Les méthodes
getElement*historiques —getElementById,getElementsByClassName,getElementsByTagName. Elles sont rapides et retournent des collections live. - Les méthodes modernes
querySelector*—querySelector,querySelectorAll. Elles acceptent n'importe quel sélecteur CSS et retournent des résultats statiques.
Ce guide couvre les deux familles, les utilitaires matches, closest et contains pour vérifier et parcourir l'arbre, et le piège le plus important : la différence entre une collection live et une collection statique. Chaque exemple est exécutable, vous pouvez donc voir le résultat immédiatement.
Une fois que vous savez trouver un élément, les étapes suivantes sont généralement parcourir le DOM pour atteindre ses voisins et manipuler le DOM pour le modifier. Pour une vue d'ensemble plus douce, consultez sélectionner les éléments DOM.
Accès efficace aux éléments : getElementById
La méthode getElementById est le moyen le plus rapide et le plus fiable d'accéder à un seul élément, car un ID est censé être unique dans un document et les navigateurs indexent les IDs en interne. Elle retourne l'élément correspondant, ou null si aucun élément avec cet ID n'existe — protégez-vous donc contre null avant d'utiliser le résultat. Notez que vous passez l'ID brut, sans le # initial (c'est uniquement pour les sélecteurs CSS). Dans l'exemple ci-dessous, le "Default text" initial est immédiatement remplacé.
<!-- snippet: html-result -->
<!DOCTYPE html>
<html>
<head>
<title>getElementById Example</title>
</head>
<body>
<div id="main-content">Default text</div>
<script>
const element = document.getElementById('main-content');
element.innerHTML = "Modified text!"
</script>
</body>
</html>Accéder à plusieurs éléments : getElementsByClassName et getElementsByTagName
Lorsque vous sélectionnez des éléments par nom de classe ou par nom de balise, vous obtenez une HTMLCollection. Il s'agit d'une collection live : elle se met à jour automatiquement lorsque le DOM change. Elle ressemble à un array — vous pouvez lire les éléments par index (els[0]) et vérifier els.length — mais ce n'est pas un véritable array, donc elle ne possède pas forEach, map ou filter. Pour l'itérer en toute sécurité, convertissez-la d'abord avec Array.from(...) (ou le spread [...els]).
Exemple avec getElementsByClassName
Accédez à plusieurs éléments ayant la même classe en utilisant getElementsByClassName. Dans cet exemple, nous avons deux éléments div avec le même nom de classe. Nous les modifions tous les deux en sélectionnant ces éléments par leur nom de classe.
<!-- snippet: html-result -->
<!DOCTYPE html>
<html>
<head>
<title>getElementsByClassName Example</title>
</head>
<body>
<div class="info">First Info</div>
<div class="info">Second Info</div>
<script>
const infoElements = document.getElementsByClassName('info');
Array.from(infoElements).forEach(el => el.innerHTML = "MODIFIED!");
</script>
</body>
</html>Exemple avec getElementsByTagName
Récupérez les éléments par leur nom de balise avec getElementsByTagName. C'est tout à fait similaire au précédent, mais cette fois nous sélectionnons par le nom de balise, et non par le nom de classe.
<!-- snippet: html-result -->
<!DOCTYPE html>
<html>
<head>
<title>getElementsByTagName Example</title>
</head>
<body>
<p>First Paragraph</p>
<p>Second Paragraph</p>
<script>
const paragraphs = document.getElementsByTagName('p');
Array.from(paragraphs).forEach(el => el.innerHTML = "MODIFIED!");
</script>
</body>
</html>Recherches flexibles avec querySelector et querySelectorAll
Sélectionner avec querySelector
Utilisez querySelector pour trouver le premier élément correspondant à un sélecteur CSS. Dans cet exemple, nous sélectionnons le premier élément avec la classe text qui est un enfant direct de l'élément avec l'id main.
<!-- snippet: html-result -->
<!DOCTYPE html>
<html>
<head>
<title>QuerySelector Example</title>
</head>
<body>
<div id="main"><span class="text">This will be replaced</span></div>
<div id="other"><span class="text">This one doesn't change</span></div>
<script>
const spanInsideDiv = document.querySelector('#main > .text');
spanInsideDiv.innerHTML = "MODIFIED!";
</script>
</body>
</html>Récupérer plusieurs éléments avec querySelectorAll
querySelectorAll retourne tous les éléments correspondant à un sélecteur CSS, sous forme d'une NodeList statique. Pratiquement, une NodeList possède un forEach intégré, vous pouvez donc la parcourir directement sans la convertir en array au préalable.
Le mot statique est important : querySelectorAll prend un instantané des correspondances au moment où vous l'appelez. Si vous ajoutez ou supprimez des éléments correspondants par la suite, cet instantané ne change pas. C'est exactement le contraire de la HTMLCollection live retournée par les méthodes getElementsBy*.
<!-- snippet: html-result -->
<!DOCTYPE html>
<html>
<head>
<title>QuerySelectorAll Example</title>
</head>
<body>
<ul>
<li class="item">Item 1</li>
<li class="item">Item 2</li>
</ul>
<script>
const items = document.querySelectorAll('.item');
items.forEach(item => item.innerHTML = "MODIFIED!");
</script>
</body>
</html>Live vs. statique : le piège des collections
C'est le piège qui surprend la plupart des débutants. Une HTMLCollection live reflète l'état actuel du DOM à chaque lecture, tandis qu'une NodeList statique est figée au moment de la sélection. L'extrait ci-dessous montre les deux réagissant à un élément nouvellement ajouté :
// Suppose the page has two <li class="item"> elements.
const live = document.getElementsByClassName('item'); // live HTMLCollection
const snapshot = document.querySelectorAll('.item'); // static NodeList
console.log(live.length); // 2
console.log(snapshot.length); // 2
// Now add a third matching element.
const li = document.createElement('li');
li.className = 'item';
document.querySelector('ul').appendChild(li);
console.log(live.length); // 3 — updated automatically
console.log(snapshot.length); // 2 — still the old snapshotPourquoi c'est important : parcourir en boucle une collection live tout en supprimant des éléments correspondants est une source classique d'éléments ignorés, car la collection rétrécit sous vos pieds. Une NodeList statique issue de querySelectorAll est plus sûre dans ce cas, puisque la liste ne changera pas en milieu de boucle.
Vérifier et parcourir : matches, closest et contains
La recherche ne consiste pas seulement à trouver des éléments — souvent vous avez un élément et devez lui poser une question.
element.matches(selector)retournetruesi l'élément lui-même correspond au sélecteur CSS. Idéal pour la délégation d'événements.element.closest(selector)remonte vers le haut de l'arbre depuis l'élément (lui-même inclus) et retourne l'ancêtre le plus proche qui correspond, ounull.parent.contains(node)retournetruesinodeest le parent lui-même ou un de ses descendants.
<!-- snippet: html-result -->
<!DOCTYPE html>
<html>
<body>
<section class="card">
<button id="save" class="btn primary">Save</button>
</section>
<div id="out"></div>
<script>
const btn = document.getElementById('save');
const section = document.querySelector('.card');
const out = document.getElementById('out');
out.innerHTML =
'matches(".primary"): ' + btn.matches('.primary') + '<br>' +
'closest(".card") is section: ' + (btn.closest('.card') === section) + '<br>' +
'section.contains(btn): ' + section.contains(btn);
</script>
</body>
</html>Quelle méthode utiliser ?
- Besoin d'un seul élément par ID ? Utilisez
getElementById— c'est le plus rapide et le plus clair. - Besoin d'un sélecteur CSS (descendants, combinateurs, attributs,
:not()) ? UtilisezquerySelector/querySelectorAll. - Besoin d'une liste live qui suit les changements du DOM ? Utilisez
getElementsByClassName/getElementsByTagName. - Vous avez un élément et devez tester ou remonter l'arbre ? Utilisez
matches,closestoucontains.
Conclusion
Trouver des éléments est le fondement de tout script DOM. Faites appel à getElementById pour les ID uniques, à querySelector* pour la flexibilité des sélecteurs CSS, et aux méthodes getElementsBy* quand vous avez vraiment besoin d'une collection live — souvenez-vous simplement de la différence live/statique pour que les collections ne vous surprennent pas en milieu de boucle. À partir d'ici, continuez avec parcourir le DOM et la manipulation du DOM.