Le JavaScript, en tant que langage côté client, s'exécute au sein d'un environnement navigateur. Deux interfaces clés facilitent cette interaction : le Modèle Objet du Navigateur (BOM) et le Modèle Objet du Document (DOM). Tandis que le BOM sert de pont entre votre code JavaScript et les fonctionnalités du navigateur, le DOM est l'interface dédiée à la manipulation des éléments structurant une page web.
Le BOM englobe des objets fondamentaux tels que window, history, et location. Le DOM, quant à lui, est structuré autour d'objets comme Document (représentant l'intégralité du document), Element (pour les balises HTML individuelles), CharacterData (pour les données textuelles), et Attr (pour les attributs des éléments). Ces entités DOM peuvent être subdivisées davantage, reflétant la granularité de la structure d'un document HTML.
Il est important de noter que de nombreux objets DOM, ainsi que l'objet global window, héritent de EventTarget, ce qui leur confère des méthodes d'instance pour la gestion des événements. L'objet document est une instance de HTMLDocument, qui hérite lui-même d'une chaîne de prototypes.
console.log(window.__proto__); // Affiche Window.prototype
console.log(window.__proto__.__proto__); // Affiche EventTarget.prototype
console.log(window.__proto__.__proto__.__proto__); // Affiche Object.prototype
console.log(document.__proto__); // Affiche HTMLDocument.prototype
console.log(document.__proto__.__proto__); // Affiche Document.prototype
console.log(document.__proto__.__proto__.__proto__); // Affiche Node.prototype
console.log(document.__proto__.__proto__.__proto__.__proto__); // Affiche EventTarget.prototype
console.log(document.__proto__.__proto__.__proto__.__proto__.__proto__); // Affiche Object.prototype
L'interface EventTarget
L'interface EventTarget définit trois méthodes esesntielles, disponibles sur l'objet window ainsi que sur la plupart des éléments DOM :
addEventListener(): Permet d'attacher un gestionnaire d'événements à un élément.removeEventListener(): Permet de supprimer un gestionnaire d'événements précédemment attaché.dispatchEvent(): Permet de déclencher un événement sur un élément de manière programmatique.
Voici un exemple simple d'utilisation pour écouter un clic sur la fenêtre globale :
window.addEventListener('click', (evenement) => {
console.log('La fenêtre du navigateur a été cliquée.');
});
Le Modèle Objet du Navigateur (BOM)
Le BOM est principalement composé des objets suivants :
window: L'objet global qui contient également des propriétés et méthodes pour contrôler la fenêtre du navigateur.history: Fournit un accès à l'historique de session du navigateur.location: Offre des informations détaillées sur l'URL actuelle.document: L'objet du document actuel, que nous explorerons plus en détail dans la section DOM.
L'objet window
L'objet window joue un double rôle fondamental dans l'environnement du navigateur :
1. En tant qu'objet global
Dans ce rôle, window est la portée globale pour le code JavaScript. Ses principales implications sont :
- Les variables déclarées avec
var(hors d'une fonction) sont attachées à l'objetwindow. - Il fournit des fonctions globales comme
setTimeout(),setInterval(), ainsi que l'accès à d'autres objets globaux commeMathetDate.
var nomUtilisateur = "Alice Dubois";
console.log(window.nomUtilisateur); // Affiche "Alice Dubois"
window.setTimeout(() => {
console.log("Ceci s'exécute après un délai.");
}, 500);
2. En tant qu'objet de la fenêtre du navigateur
Dans ce rôle, window gère l'interaction avec la fenêtre du navigateur elle-même. Il inclut :
- De nombreuses propriétés relatives à la fenêtre et à l'affichage (ex:
localStorage,console,location,history,screenX,scrollX,innerHeight, etc.). - Un large éventail de méthodes pour manipuler la fenêtre (ex:
alert(),close(),scrollTo(),open(),print(), etc.). - Divers événements liés à la fenêtre (ex:
focus,blur,load,hashchange,resize). - Les méthodes
addEventListener(),removeEventListener()etdispatchEvent()héritées deEventTarget.
Il est courant d'omettre le préfixe window. lors de l'accès à ses propriétés ou méthodes.
console.log(`Position horizontale de la fenêtre : ${window.screenX}px`);
console.log("Objet console :", console); // Accès direct à l'objet console
// Défilement de la page à une position spécifique
scrollTo(0, 400); // Équivalent à window.scrollTo(0, 400)
window.addEventListener('load', () => {
console.log("La page entière (y compris les ressources) est chargée.");
});
L'objet location
L'objet location fournit des informations détaillées sur l'URL de la page actuelement chargée, ainsi que des méthodes pour manipuler cette URL :
hash: La partie de l'URL commençant par '#', souvent utilisée pour les ancres internes.host: Le nom d'hôte et le port (ex: "www.exemple.com:8080").hostname: Le nom d'hôte sans le port (ex: "www.exemple.com").href: L'URL complète de la page.pathname: Le chemin du fichier ou de la ressource sur le serveur (ex: "/pages/produit.html").port: Le numéro de port HTTP/HTTPS.protocol: Le protocole utilisé (ex: "http:", "https:").
Les méthodes courantes de location incluent :
assign(url): Charge une nouvelle ressourrce à l'URL spécifiée. L'ancienne page est ajoutée à l'historique du navigateur.replace(url): Remplace la ressource actuelle par l'URL spécifiée. La page actuelle n'est PAS ajoutée à l'historique, empêchant ainsi le retour à celle-ci via le bouton "précédent".reload(forceGet): Recharge la page actuelle. SiforceGetest vrai, le navigateur force un rechargement depuis le serveur.
L'objet history
L'objet history permet d'interagir avec l'historique des sessions du navigateur. Il possède deux propriétés principales :
length: Le nombre d'entrées dans l'historique de session.state: L'état associé à l'entrée d'historique actuelle, défini parpushState()oureplaceState().
Ses méthodes principales sont :
pushState(state, title, url): Ajoute une nouvelle entrée à l'historique de session.stateest un objet à conserver,titleest le titre de la page (souvent ignoré par les navigateurs), eturlest la nouvelle URL.replaceState(state, title, url): Modifie l'entrée actuelle de l'historique de session.go(delta): Navigue dedeltaentrées dans l'historique (ex:history.go(-1)pour reculer,history.go(1)pour avancer).back(): Recule d'une page dans l'historique, équivalent àhistory.go(-1).forward(): Avance d'une page dans l'historique, équivalent àhistory.go(1).
window.addEventListener('DOMContentLoaded', () => {
const boutonModifierHistorique = document.createElement('button');
boutonModifierHistorique.textContent = 'Ajouter une entrée à l\'historique';
document.body.appendChild(boutonModifierHistorique);
boutonModifierHistorique.addEventListener('click', () => {
history.pushState({ idProduit: 'xyz', categorie: 'electronique' }, 'Détail Produit', '/produits/detail-xyz');
console.log(`Longueur de l'historique : ${history.length}`);
console.log('État stocké :', history.state);
});
});
Le Modèle Objet du Document (DOM)
Le DOM est l'API qui permet aux langages de script, comme JavaScript, d'accéder et de manipuler les structures et le contenu des documents HTML et XML. Tous les éléments DOM héritent de EventTarget et de Node, leur conférant ainsi un ensemble commun de propriétés et méthodes.
La hiérarchie des objets DOM est vaste, mais elle peut être simplifiée en ces catégories principales :
Document: Représente le document entier (ex:HTMLDocument,XMLDocument).Element: Représente une balise HTML ou XML (ex:HTMLElement,HTMLDivElement,HTMLImageElement).CharacterData: Représente du texte ou des commentaires (ex:Textpour le contenu textuel,Commentpour les commentaires).Attr: Représente un attribut d'un élément (ex:name="valeur",class="style").
L'objet Node
L'interface Node est le parent de la plupart des types d'objets du DOM. Par conséquent, les propriétés et méthodes définies sur Node sont disponibles sur de nombreux objets DOM enfants. Parmi les plus courantes, on trouve :
nodeName: Le nom du nœud (ex: "DIV", "#text", "#document").nodeType: Le type numérique du nœud (ex: 1 pour un élément, 3 pour du texte, 8 pour un commentaire, 9 pour le document).nodeValue: La valeur textuelle du nœud (nullpour les éléments, le contenu pour les nœuds de texte).childNodes: UneNodeListde tous les enfants du nœud (y compris les nœuds de texte et de commentaire).appendChild(childNode): Méthode pour ajouter un nœud enfant à la fin de la liste des enfants.
Exemple avec un élément HTML et son contenu textuel :
<div id="zone-contenu">Ceci est un paragraphe de texte.</div>
const elementContenu = document.getElementById("zone-contenu");
console.log(`Nom du nœud : ${elementContenu.nodeName}`); // Affiche "DIV"
console.log(`Type de nœud : ${elementContenu.nodeType}`); // Affiche 1 (ELEMENT_NODE)
console.log(`Valeur du nœud (pour Element, c'est null) : ${elementContenu.nodeValue}`); // Affiche null
console.log('Nœuds enfants :', elementContenu.childNodes); // Affiche NodeList [text]
console.log(`Valeur du premier enfant (texte) : ${elementContenu.childNodes[0].nodeValue}`); // Affiche "Ceci est un paragraphe de texte."
console.log(`Nom du nœud Document : ${document.nodeName}`); // Affiche "#document"
console.log(`Type du nœud Document : ${document.nodeType}`); // Affiche 9 (DOCUMENT_NODE)
console.log(`Valeur du nœud Document : ${document.nodeValue}`); // Affiche null
console.log('Nœuds enfants du Document :', document.childNodes); // Affiche NodeList [, html]
L'objet Document
L'objet document est une instance de HTMLDocument qui représente la page HTML entière chargée dans le navigateur. Il est créé une fois que le navigateur a terminé d'analyser le document. Cet objet est le point d'entrée principal pour la manipulation du contenu de la page.
Parmi ses propriétés et méthodes les plus courantes, on trouve :
body: Accède à l'élément<body>du document.head: Accède à l'élément<head>du document.title: Obtient ou définit le titre du document.children: UneHTMLCollectiondes éléments enfants directs du document (généralement<html>).location: Similaire àwindow.location, fournit des informations sur l'URL.
Méthodes essentielles pour la manipulation des éléments :
createElement(tagName): Crée un nouvel élément HTML avec le nom de balise spécifié.removeChild(childNode): Supprime un nœud enfant spécifié de son parent. (Note: l'élément lui-même a une méthode.remove()).appendChild(childNode): Hérité deNode, ajoute un nœud enfant à la fin.querySelector(selector): Retourne le premier élément qui correspond au sélecteur CSS spécifié.querySelectorAll(selector): Retourne uneNodeListde tous les éléments qui correspondent au sélecteur CSS spécifié.getElementById(id): Retourne l'élément dont l'attributidcorrespond à la chaîne spécifiée.getElementsByName(name): Retourne uneNodeListd'éléments dont l'attributnamecorrespond à la chaîne spécifiée.getElementsByTagName(tagName): Retourne uneHTMLCollectiond'éléments dont le nom de balise est spécifié.
<body>
<header>
<h1>Bienvenue</h1>
</header>
<main>
<p>Un paragraphe initial.</p>
</main>
</body>
const nouveauDiv = document.createElement("div");
nouveauDiv.textContent = "Contenu généré dynamiquement.";
document.body.appendChild(nouveauDiv);
const elementHeader = document.getElementsByTagName("header")[0];
if (elementHeader) {
document.body.removeChild(elementHeader);
console.log("L'élément <header> a été retiré.");
}
const tousLesElementsP = document.querySelectorAll("p");
console.log("Tous les éléments <p> sur la page :", tousLesElementsP);
L'objet Element
L'objet Element représente un élément HTML spécifique (par exemple, <div>, <img>, <p>). Il possède des propriétés et méthodes pour interagir avec cet élément particulier :
children: UneHTMLCollectiondes éléments enfants (exclut les nœuds texte/commentaire).childNodes: Hérité deNode, inclut tous les nœuds enfants (éléments, texte, commentaires).tagName: Le nom de la balise de l'élément en majuscules (ex: "DIV", "P").id: La valeur de l'attributid.className: La valeur de l'attributclass.classList: Un objetDOMTokenListqui gère les classes CSS de l'élément (add,remove,toggle,contains).clientWidth,clientHeight: La largeur et la hauteur de l'élément, y compris le padding mais sans la bordure ni la marge.clientLeft,clientTop: La largeur de la bordure gauche et supérieure de l'élément.offsetWidth,offsetHeight: La largeur et la hauteur de l'élément, y compris le padding et la bordure, mais sans la marge.offsetLeft,offsetTop: La position (X, Y) de l'élément par rapport à sonoffsetParent.getAttribute(name): Récupère la valeur d'un attribut spécifié.setAttribute(name, value): Définit la valeur d'un attribut spécifié.
<div id="card-produit" class="produit en-stock">
<h2>Titre du Produit</h2>
<p>Description brève.</p>
</div>
.produit {
height: 180px;
width: 300px;
border: 5px solid #ccc;
padding: 10px;
margin: 20px;
background-color: #f9f9f9;
}
const carteProduit = document.getElementById("card-produit");
console.log('Enfants éléments (balises) :', carteProduit.children); // Affiche [h2, p]
console.log('Nœuds enfants (tous types) :', carteProduit.childNodes); // Affiche [text, h2, text, p, text]
console.log(`Nom de la balise : ${carteProduit.tagName}`); // Affiche "DIV"
console.log(`ID : ${carteProduit.id}`); // Affiche "card-produit"
console.log(`Nom de classe : ${carteProduit.className}`); // Affiche "produit en-stock"
console.log('Liste de classes :', carteProduit.classList); // Affiche DOMTokenList ["produit", "en-stock"]
console.log(`Largeur interne (contenu + padding) : ${carteProduit.clientWidth}px`); // 300 + (2*10) = 320 -> 300px (content + padding)
console.log(`Hauteur interne (contenu + padding) : ${carteProduit.clientHeight}px`); // 180 + (2*10) = 200 -> 180px (content + padding)
console.log(`Largeur de la bordure gauche : ${carteProduit.clientLeft}px`); // 5px
console.log(`Largeur de la bordure supérieure : ${carteProduit.clientTop}px`); // 5px
console.log(`Largeur totale (incluant bordures et padding) : ${carteProduit.offsetWidth}px`); // 300 + 2*10 + 2*5 = 330px
console.log(`Hauteur totale (incluant bordures et padding) : ${carteProduit.offsetHeight}px`); // 180 + 2*10 + 2*5 = 210px
console.log(`Position X par rapport au parent offset : ${carteProduit.offsetLeft}px`); // Dépend du positionnement du parent
console.log(`Position Y par rapport au parent offset : ${carteProduit.offsetTop}px`); // Dépend du positionnement du parent
console.log(`Valeur de l'attribut 'id' : ${carteProduit.getAttribute("id")}`); // Affiche "card-produit"
carteProduit.setAttribute("data-disponibilite", "immédiate"); // Ajoute un nouvel attribut
console.log(`Nouvel attribut 'data-disponibilite' : ${carteProduit.getAttribute("data-disponibilite")}`);