Manipulation des Nœuds DOM
Cette section explore les opérations fondamentales de manipulation des nœuds dans le Document Object Model (DOM), incluant la suppression, le clonage et la création d'éléments.
Suppression de Nœuds
La méthode parentNode.removeChild(childNode) est utilisée pour retirer un nœud enfant spécifié de son parent dans le DOM. Elle renvoie le nœud qui a été supprimé.
<button id="boutonSupprimerPremier">Supprimer le premier élément de la liste</button>
<ul id="listeElements">
<li>Élément numéro un</li>
<li>Élément numéro deux</li>
<li>Élément numéro trois</li>
</ul>
const listeParent = document.getElementById('listeElements');
const boutonAction = document.getElementById('boutonSupprimerPremier');
boutonAction.addEventListener('click', () => {
if (listeParent.children.length > 0) {
listeParent.removeChild(listeParent.firstElementChild);
} else {
boutonAction.disabled = true; // Désactive le bouton s'il n'y a plus d'éléments
console.log("Tous les éléments ont été supprimés.");
}
});
Exemple : Système de Commentaires Simple
Ce cas pratique illustre comment ajouter dynamiquement des commentaires à une liste et offrir une option pour les suppprimer individuellement.
<textarea id="champCommentaire" placeholder="Écrivez votre message..."></textarea>
<button id="boutonPublier">Publier</button>
<ul id="zoneCommentaires"></ul>
const btnPublier = document.getElementById('boutonPublier');
const textareaCommentaire = document.getElementById('champCommentaire');
const listeCommentaires = document.getElementById('zoneCommentaires');
btnPublier.addEventListener('click', () => {
const texteMessage = textareaCommentaire.value.trim();
if (texteMessage === '') {
alert('Veuillez saisir du texte avant de publier.');
return;
}
const nouvelArticle = document.createElement('li');
const contenuCommentaire = document.createElement('span');
contenuCommentaire.textContent = texteMessage;
const lienSuppression = document.createElement('a');
lienSuppression.href = 'javascript:;';
lienSuppression.textContent = ' (effacer)';
lienSuppression.addEventListener('click', function() {
listeCommentaires.removeChild(nouvelArticle); // Retire le 'li' entier
});
nouvelArticle.appendChild(contenuCommentaire);
nouvelArticle.appendChild(lienSuppression);
// Ajoute le nouveau commentaire en début de liste
if (listeCommentaires.firstElementChild) {
listeCommentaires.insertBefore(nouvelArticle, listeCommentaires.firstElementChild);
} else {
listeCommentaires.appendChild(nouvelArticle);
}
textareaCommentaire.value = ''; // Vide le champ de saisie
});
Clonage de Nœuds
La méthode node.cloneNode(deep) permet de créer une copie d'un nœud existant. Le paramètre optionnel deep (un booléen) détermine si les nœuds enfants doivent également être clonés :
- Si
false(ou omis), une copie superficielle est effectuée (seul le nœud est cloné, sans ses descendants). - Si
true, une copie profonde est réalisée (le nœud et tous ses enfants et descendants sont clonés).
<ul id="listeOriginale">
<li>Article A</li>
<li>Article B</li>
<li>Article C</li>
</ul>
const sourceListe = document.getElementById('listeOriginale');
const premierArticle = sourceListe.firstElementChild; // Le premier LI
// Effectuer un clonage profond du premier article
const cloneProfond = premierArticle.cloneNode(true);
cloneProfond.textContent = "Copie de " + premierArticle.textContent; // Modifier le texte pour le distinguer
// Ajouter le clone à la liste existante
sourceListe.appendChild(cloneProfond);
// Un exemple de clonage superficiel (pour illustration, non ajouté au DOM)
const cloneSuperficiel = premierArticle.cloneNode(false);
console.log("Contenu du clone superficiel (devrait être vide si l'original avait des enfants) :", cloneSuperficiel.textContent);
Exemple : Génération Dynamique d'un Tableau de Données
Cet exemple construit un tableau HTML en injectant des données d'étudiants, et ajoute une fonctionnalité pour supprimer des lignes individuellement.
<table border="1" style="width:100%; border-collapse: collapse;">
<thead>
<tr>
<th style="padding: 8px;">Nom</th>
<th style="padding: 8px;">Matière</th>
<th style="padding: 8px;">Note</th>
<th style="padding: 8px;">Action</th>
</tr>
</thead>
<tbody id="corpsTableauEtudiants"></tbody>
</table>
const donneesEtudiants = [
{ nom: 'Léa', cours: 'Frontend Dev', note: 92 },
{ nom: 'Max', cours: 'Backend Dev', note: 85 },
{ nom: 'Chloé', cours: 'UI/UX Design', note: 95 },
{ nom: 'Tom', cours: 'Data Science', note: 88 }
];
const tableauCorps = document.getElementById('corpsTableauEtudiants');
donneesEtudiants.forEach(etudiant => {
const ligne = document.createElement('tr');
// Ajout des cellules de données pour chaque propriété de l'étudiant
for (const propriete in etudiant) {
const cellule = document.createElement('td');
cellule.textContent = etudiant[propriete];
cellule.style.padding = '8px';
ligne.appendChild(cellule);
}
// Ajout de la cellule d'action (suppression)
const celluleAction = document.createElement('td');
const lienSupprimer = document.createElement('a');
lienSupprimer.href = 'javascript:;';
lienSupprimer.textContent = 'Supprimer cette ligne';
lienSupprimer.style.color = 'red';
lienSupprimer.style.textDecoration = 'none';
lienSupprimer.addEventListener('click', function() {
tableauCorps.removeChild(ligne); // Supprime la ligne parente du lien
});
celluleAction.appendChild(lienSupprimer);
celluleAction.style.padding = '8px';
ligne.appendChild(celluleAction);
tableauCorps.appendChild(ligne);
});
Méthodes de Création d'Éléments DOM
Plusieurs approches existent pour ajouter des éléments au DOM via JavaScript, chacune adaptée à des scénarios spécifiques.
<button id="boutonEcrireDoc">Tester document.write()</button>
<div class="conteneur-inner" style="border: 1px dashed blue; padding: 10px; margin-top: 10px;"></div>
<div class="conteneur-create" style="border: 1px dashed green; padding: 10px; margin-top: 10px;"></div>
// 1. document.write(): À utiliser avec prudence. Si appelé après le chargement complet du document, il peut réinitialiser la page.
const btnDocWrite = document.getElementById('boutonEcrireDoc');
btnDocWrite.addEventListener('click', () => {
document.write('<h4>Ce texte a été inséré par document.write() !</h4><p>Attention à son usage.</p>');
});
// 2. innerHTML: Insère du contenu HTML sous forme de chaîne de caractères.
// Pour des insertions multiples, il est plus efficace de construire la chaîne complète avant d'affecter innerHTML une seule fois.
const conteneurInner = document.querySelector('.conteneur-inner');
const liensHtml = [];
for (let i = 1; i <= 5; i++) {
liensHtml.push('<a href="#" style="margin-right: 5px;">Lien ' + i + '</a>');
}
conteneurInner.innerHTML = '<h3>Éléments créés avec innerHTML</h3>' + liensHtml.join('');
// 3. document.createElement(): La méthode la plus courante pour créer des nœuds DOM individuels de manière programmatique.
const conteneurCreate = document.querySelector('.conteneur-create');
const titreCreate = document.createElement('h3');
titreCreate.textContent = 'Éléments créés avec createElement';
conteneurCreate.appendChild(titreCreate);
for (let i = 1; i <= 5; i++) {
const nouvelLien = document.createElement('a');
nouvelLien.href = '#';
nouvelLien.textContent = 'Ancre ' + i;
nouvelLien.style.marginRight = '5px';
conteneurCreate.appendChild(nouvelLien);
}
Comparaison de Performance : innerHTML vs. createElement
La création d'un grand nombre d'éléments DOM peut avoir un impact significatif sur les performances. Comparons les différentes approches.
innerHTML avec concaténation progressive (performance faible)
function testerConcatProgressive() {
const debut = performance.now();
for (let i = 0; i < 1000; i++) {
document.body.innerHTML += '<div class="boite-rouge"></div>'; // Chaque opération force un re-parsing et re-rendu
}
const fin = performance.now();
console.log(`innerHTML (concaténation progressive) : ${(fin - debut).toFixed(2)} ms`);
}
// testerConcatProgressive(); // Décommenter pour exécuter ce test
createElement (performance moyenne, optimisée avec DocumentFragment)
function testerCreateElement() {
const debut = performance.now();
const fragmentDocument = document.createDocumentFragment(); // Utilise un DocumentFragment pour minimiser les manipulations directes du DOM
for (let i = 0; i < 1000; i++) {
const nouvelleDiv = document.createElement('div');
nouvelleDiv.style.width = '100px';
nouvelleDiv.style.height = '2px';
nouvelleDiv.style.border = '1px solid blue';
fragmentDocument.appendChild(nouvelleDiv);
}
document.body.appendChild(fragmentDocument); // Ajout unique au DOM
const fin = performance.now();
console.log(`createElement (avec DocumentFragment) : ${(fin - debut).toFixed(2)} ms`);
}
// testerCreateElement(); // Décommenter pour exécuter ce test
innerHTML avec tableau et join() (performance élevée)
function testerArrayJoinInnerHTML() {
const debut = performance.now();
const tableauDivs = [];
for (let i = 0; i < 1000; i++) {
tableauDivs.push('<div class="boite-verte"></div>');
}
document.body.innerHTML += tableauDivs.join(''); // Un seul accès au DOM avec une chaîne construite
const fin = performance.now();
console.log(`innerHTML (tableau + join) : ${(fin - debut).toFixed(2)} ms`);
}
// testerArrayJoinInnerHTML(); // Décommenter pour exécuter ce test
Gestion Avancée des Événements DOM
Enregistrement des Événements (Écouteurs)
Deux méthodes principales sont utilisées pour attacher des gestionnaires d'événements à des éléments DOM, chacune avec son propre ensemble de compatibilités et de fonctionnalités.
addEventListener() (Standard W3C - Supporté par IE9 et versions ultérieures)
La méthode eventTarget.addEventListener() est la méthode standard pour attacher un gestionnaire d'événements. Elle permet d'attacher plusieurs gestionnaires pour le même type d'événement sur un même élément.
- Le type d'événement est une chaîne de caractères (par exemple,
'click', sans le préfixe'on'). - Le troisième paramètre (un booléen) est optionnel et spécifie si l'événement doit être géré en phase de capture (
true) ou de bouillonnement (falseou omis).
attachEvent() (Spécifique à IE6-IE8)
La méthode eventTarget.attachEvent() est l'équivalent pour les anciennes versions d'Internet Explorer. Elle n'est plus recommandée pour les navigateurs modernes.
<button id="btnAncien">Enregistrement Ancien</button>
<button id="btnModerne">Enregistrement Moderne (addEventListener)</button>
<button id="btnCompatIE">Enregistrement IE (attachEvent)</button>
const btnAncien = document.getElementById('btnAncien');
const btnModerne = document.getElementById('btnModerne');
const btnCompatIE = document.getElementById('btnCompatIE');
// 1. Enregistrement traditionnel (un seul gestionnaire par événement)
btnAncien.onclick = function() {
alert('Bonjour depuis le gestionnaire 1!');
};
// Le deuxième gestionnaire écrase le premier pour la méthode traditionnelle
btnAncien.onclick = function() {
alert('Rebonjour depuis le gestionnaire 2!');
};
// 2. addEventListener (permet plusieurs gestionnaires pour le même événement)
btnModerne.addEventListener('click', function() {
alert('Clic détecté par addEventListener (fonction A).');
});
btnModerne.addEventListener('click', function() {
alert('Clic détecté par addEventListener (fonction B).');
});
// 3. attachEvent (pour les anciennes versions d'IE)
// On vérifie la présence de la méthode pour la compatibilité
if (btnCompatIE.attachEvent) {
btnCompatIE.attachEvent('onclick', function() { // Notez le 'on' préfixe pour attachEvent
alert('Clic détecté par attachEvent (IE).');
});
} else {
// Fallback pour les navigateurs modernes si attachEvent n'est pas disponible
btnCompatIE.addEventListener('click', function() {
alert('attachEvent non supporté, événement géré par addEventListener.');
});
}
Solution de Compatibilité pour l'Enregistrement d'Événements
Pour écrire du code qui fonctionne sur les navigateurs anciens et modernes, on peut encapsuler la logique dans une fonction utilitaire.
function attacherEvenement(elementCible, typeEvenement, gestionnaire) {
if (elementCible.addEventListener) {
elementCible.addEventListener(typeEvenement, gestionnaire, false); // Utilisation du mode bouillonnement par défaut
} else if (elementCible.attachEvent) {
elementCible.attachEvent('on' + typeEvenement, gestionnaire); // Nécessite 'on' pour attachEvent
} else {
elementCible['on' + typeEvenement] = gestionnaire; // Méthode de secours pour les très vieux navigateurs
}
}
// Exemple d'utilisation:
const maDivTest = document.createElement('div');
maDivTest.textContent = 'Cliquez moi (compatible)';
document.body.appendChild(maDivTest);
attacherEvenement(maDivTest, 'click', function() {
console.log('Événement géré de manière compatible.');
});
Suppression d'Événements (Détachemnet)
Il est important de retirer les gestionnaires d'événements qui ne sont plus nécessaires, notamment pour prévenir les fuites de mémoire dans les applications complexes.
<div id="blocUn" style="background-color: lightblue; padding: 15px; margin-bottom: 5px; cursor: pointer;">Clickez pour retirer l'événement traditionnel</div>
<div id="blocDeux" style="background-color: lightgreen; padding: 15px; margin-bottom: 5px; cursor: pointer;">Clickez pour retirer l'événement standard</div>
<div id="blocTrois" style="background-color: lightsalmon; padding: 15px; cursor: pointer;">Clickez pour retirer l'événement IE</div>
const divUn = document.getElementById('blocUn');
const divDeux = document.getElementById('blocDeux');
const divTrois = document.getElementById('blocTrois');
// 1. Suppression via la méthode traditionnelle
divUn.onclick = function gestionnaireBlocUn() {
alert('Événement sur Bloc Un déclenché et retiré!');
divUn.onclick = null; // Détache le gestionnaire d'événements
};
// 2. Suppression via removeEventListener (nécessite la même référence de fonction)
function gestionnaireBlocDeux() {
alert('Événement sur Bloc Deux déclenché et retiré!');
divDeux.removeEventListener('click', gestionnaireBlocDeux);
}
divDeux.addEventListener('click', gestionnaireBlocDeux);
// 3. Suppression via detachEvent (pour les anciennes versions d'IE)
function gestionnaireBlocTrois() {
alert('Événement sur Bloc Trois déclenché et retiré!');
if (divTrois.detachEvent) {
divTrois.detachEvent('onclick', gestionnaireBlocTrois);
} else if (divTrois.removeEventListener) { // Fallback si l'événement a été attaché avec addEventListener
divTrois.removeEventListener('click', gestionnaireBlocTrois);
}
}
// Attacher l'événement avec la fonction compatible définie précédemment ou directement pour IE
if (divTrois.attachEvent) {
divTrois.attachEvent('onclick', gestionnaireBlocTrois);
} else {
divTrois.addEventListener('click', gestionnaireBlocTrois);
}
Flux des Événements DOM
Le flux des événements DOM décrit l'ordre dans lequel les événements sont traités sur les éléments imbriqués. Quand un événement se produit sur un élément, il traverse le DOM en trois phases distinctes :
- Phase de Capture : L'événement descend de la racine du document vers l'élément cible.
- Phase Cible : L'événement atteint l'élément sur lequel il a été déclenché.
- Phase de Bouillonnement (Bubbling) : L'événement remonte de l'élément cible vers la racine du document.
Exemple de Bouillonnement d'Événements
Dans la phase de bouilllonnement, les gestionnaires d'événements sont déclenchés en partant de l'élément cible et en remontant la hiérarchie DOM.
<div class="parent-box" style="border: 2px solid green; padding: 30px;">
Conteneur Parent
<div class="child-box" style="border: 2px solid blue; padding: 20px; margin-top: 10px;">
Élément Enfant
</div>
</div>
const conteneurParent = document.querySelector('.parent-box');
const elementEnfant = document.querySelector('.child-box');
// Par défaut, addEventListener capture en phase de bouillonnement (troisième paramètre à false ou omis)
elementEnfant.addEventListener('click', () => {
console.log('Clic sur l\'enfant (bouillonnement)');
});
conteneurParent.addEventListener('click', () => {
console.log('Clic sur le parent (bouillonnement)');
});
document.body.addEventListener('click', () => {
console.log('Clic sur le body (bouillonnement)');
});
// Si vous cliquez sur "Élément Enfant", l'ordre d'affichage sera :
// "Clic sur l'enfant (bouillonnement)"
// "Clic sur le parent (bouillonnement)"
// "Clic sur le body (bouillonnement)"
Exemple de Capture d'Événements
Dans la phase de capture, les gestionnaires d'événements sont déclenchés en descendant de la racine DOM vers l'élément cible.
// Enregistrement avec le troisième paramètre `true` pour la phase de capture
conteneurParent.addEventListener('click', () => {
console.log('Capture sur le parent');
}, true); // `true` indique la phase de capture
elementEnfant.addEventListener('click', () => {
console.log('Capture sur l\'enfant');
}, true); // `true` indique la phase de capture
// Si vous cliquez sur "Élément Enfant", l'ordre d'affichage sera :
// "Capture sur le parent"
// "Capture sur l'enfant"
// (suivi des gestionnaires de bouillonnement, si présents et non stoppés)
L'Objet Événement
Lorsqu'un événement est déclenché, le navigateur crée un objet contenant des informations contextuelles sur cet événement (qui l'a déclenché, où, quel type, etc.). Cet objet est passé comme premier argument au gestionnaire d'événements.
Accéder à l'Objet Événement
<div id="divCliquable" style="width: 250px; height: 60px; background-color: lightcoral; text-align: center; line-height: 60px; margin-top: 10px;">
Cliquez-moi pour voir l'objet événement
</div>
const elementCliquable = document.getElementById('divCliquable');
elementCliquable.addEventListener('click', (evt) => {
// L'objet 'evt' (ou 'e', 'event') est directement disponible
console.log('Objet événement (standard):', evt);
// Pour la compatibilité avec les anciens IE (IE6-IE8)
const evenementCompatible = evt || window.event;
console.log('Objet événement (compatible):', evenementCompatible);
});
Distinction entre e.target et this
this(dans le contexte d'un gestionnaire d'événements régulier) fait référence à l'élément auquel le gestionnaire d'événements a été directement attaché.e.targetfait référence à l'élément DOM le plus spécifique sur lequel l'événement a été réellement déclenché (l'élément source de l'événement).
<ul id="listeProduits" style="border: 1px solid purple; padding: 15px; margin-top: 10px;">
<li>Article 1</li>
<li>Article 2 <span>(détail)</span></li>
<li>Article 3</li>
</ul>
const listeProduits = document.getElementById('listeProduits');
listeProduits.addEventListener('click', function(e) {
console.log('`this` (élément lié) :', this); // Toujours l'UL
console.log('`e.target` (élément déclencheur) :', e.target); // Peut être UL, LI ou SPAN
if (e.target.tagName === 'LI') {
e.target.style.backgroundColor = 'lightcyan';
console.log('Un LI a été cliqué.');
} else if (e.target.tagName === 'SPAN') {
e.target.parentNode.style.backgroundColor = 'lightpink'; // Change la couleur du LI parent du SPAN
console.log('Un SPAN dans un LI a été cliqué.');
}
});
Prévention du Comportement par Défaut
Certains éléments HTML ont un comportement par défaut (ex: un lien <a> navigue, un formulaire <form> soumet des données). Il est possible d'empêcher ces actions par défaut.
<a href="https://www.openai.com" id="lienOpenAI">Visiter OpenAI</a>
<form onsubmit="console.log('Formulaire soumis par défaut!'); return false;" style="margin-top: 10px;">
<button type="submit">Tester Soumission</button>
</form>
const lienBloque = document.getElementById('lienOpenAI');
// Méthode standard: event.preventDefault()
lienBloque.addEventListener('click', (e) => {
e.preventDefault(); // Empêche la navigation vers l'URL
alert('La navigation vers OpenAI a été bloquée!');
});
// Pour les gestionnaires attachés via `onclick` et la compatibilité IE:
// lienBloque.onclick = function(e) {
// e = e || window.event; // Objet événement compatible pour IE
// if (e.preventDefault) {
// e.preventDefault(); // Standard W3C
// } else {
// e.returnValue = false; // Propriété spécifique à IE
// }
// return false; // Autre méthode pour empêcher l'action par défaut dans les gestionnaires 'on...'
// };
Arrêter la Propagation d'Événements (Stopper le Bouillonnement)
Parfois, il est souhaitable d'empêcher un événement de remonter la hiérarchie DOM (le bouillonnement) pour éviter de déclencher des gestionnaires sur les éléments parents.
<div id="boiteExterieure" style="border: 2px solid red; padding: 40px; margin-top: 10px;">
<p>Zone Extérieure</p>
<div id="boiteInterieure" style="border: 2px solid blue; padding: 20px; margin-top: 10px;">
<p>Zone Intérieure (cliquez ici pour stopper)</p>
</div>
</div>
const divExterieure = document.getElementById('boiteExterieure');
const divInterieure = document.getElementById('boiteInterieure');
divExterieure.addEventListener('click', () => {
alert('Clic détecté sur la Zone Extérieure!');
});
divInterieure.addEventListener('click', (e) => {
alert('Clic détecté sur la Zone Intérieure!');
e.stopPropagation(); // Méthode standard pour arrêter la propagation
// Pour la compatibilité IE (avant IE9): e.cancelBubble = true;
});
Délégation d'Événements
La délégation d'événements (ou "event delegation") est une technique qui consiste à attacher un seul gestionnaire d'événements à un élément parent commun, plutôt qu'à chaque élément enfant individuellement. Elle exploite le principe du bouillonnement des événements.
Avantages :
- **Performance optimisée :** Moins de gestionnaires d'événements sont attachés au DOM, ce qui réduit la consommation de mémoire et améliore la fluidité.
- **Gestion des éléments dynamiques :** Les éléments ajoutés au DOM après le chargement initial hériteront automatiquement des gestionnaires d'événements délégués, sans nécessiter de réattacher des écouteurs.
<ul id="listeTaches" style="border: 1px solid gray; padding: 10px; margin-top: 10px;">
<li>Faire les courses</li>
<li>Préparer le dîner</li>
<li>Apprendre le DOM</li>
</ul>
<button id="ajouterTache">Ajouter une nouvelle tâche</button>
const conteneurTaches = document.getElementById('listeTaches');
const boutonAjouter = document.getElementById('ajouterTache');
let compteurTaches = 3;
// Le gestionnaire est attaché au parent (ul)
conteneurTaches.addEventListener('click', (e) => {
// On vérifie si l'élément cliqué est bien un LI
if (e.target.tagName === 'LI') {
e.target.style.backgroundColor = 'lightyellow';
console.log(`Tâche complétée : ${e.target.textContent}`);
}
});
boutonAjouter.addEventListener('click', () => {
compteurTaches++;
const nouvelleTache = document.createElement('li');
nouvelleTache.textContent = `Nouvelle tâche ${compteurTaches}`;
conteneurTaches.appendChild(nouvelleTache);
});
Événements de Souris Courants
Désactiver la Sélection de Texte et le Menu Contextuel
Il est possible de contrôler certains comportements par défaut du navigateur liés à la souris, comme la sélection de texte ou l'ouverture du menu contextuel (clic droit).
<body>
<p>Ce paragraphe ne permet pas la sélection de texte.</p>
<p>Faites un clic droit ici; le menu contextuel est désactivé.</p>
</body>
// Empêcher l'affichage du menu contextuel (clic droit)
document.addEventListener('contextmenu', (e) => {
e.preventDefault(); // Bloque l'action par défaut du clic droit
alert('Le menu contextuel est désactivé sur cette page!');
});
// Empêcher la sélection de texte (sur la plupart des navigateurs)
document.addEventListener('selectstart', (e) => {
e.preventDefault(); // Bloque l'action par défaut de la sélection de texte
console.log('La sélection de texte est actuellement désactivée.');
});
Propriétés de l'Objet Événement de Souris
L'objet événement des événements de souris fournit diverses propriétés pour obtenir les coordonnées du pointeur sur l'écran ou le document.
clientX,clientY: Coordonnées du pointeur par rapport au bord gauche/haut de la zone visible (viewport) du navigateur.pageX,pageY: Coordonnées du pointeur par rapport au bord gauche/haut du document HTML entier.screenX,screenY: Coordonnées du pointeur par rapport au bord gauche/haut de l'écran physique de l'utilisateur.
document.addEventListener('mousemove', (e) => {
console.log('--- Coordonnées du pointeur ---');
console.log(`Client (Viewport): X = ${e.clientX}, Y = ${e.clientY}`);
console.log(`Page (Document) : X = ${e.pageX}, Y = ${e.pageY}`);
console.log(`Écran (Screen) : X = ${e.screenX}, Y = ${e.screenY}`);
});
Exemple : Une Image Suivant le Pointeur de la Souris
Créez une image qui se déplace pour suivre le curseur de la souris partout sur la page.
<img id="imageSuiveuse" src="images/angel.gif" alt="Ange volant" style="position: absolute; left: 0; top: 0; pointer-events: none;">
const imageASuivre = document.getElementById('imageSuiveuse');
document.addEventListener('mousemove', (e) => {
// Ajuster la position pour centrer l'image sous le curseur
// Ces valeurs dépendent de la taille réelle de votre image.
// Si l'image fait 100x80px, un décalage de -50px pour X et -40px pour Y la centrera.
const decalageX = 50;
const decalageY = 40;
imageASuivre.style.left = (e.pageX - decalageX) + 'px';
imageASuivre.style.top = (e.pageY - decalageY) + 'px';
});