Manipulation des nœuds
Typage des nœuds
Les nœuds dans DOM sont associés à des types spécifiques en JS. Ils reflètent la structure et le contenu de la page web. Les nœuds sont typés. Chaque nœud correspond à un élément spécifique du DOM. Chaque
nœud a une propriété nodeType parmi 12 possibles : ELEMENT_NODE
, TEXT_NODE
, ATTRIBUTE_NODE
, COMMENT_NODE
, ...
Ces types facilitent la manipulation précise des données dans le DOM en permettant aux développeurs d'appliquer des opérations spécifiques en fonction du type de nœud.
<html>
<head>
<title>Page exemple</title>
</head>
</head>
<body>
<h1 id ="titre">Titre</h1>
<p id = "paragraphe1"> Bonjour </p>
<div id="images">
<img src="https://www.iut.u-bordeaux.fr/info/assets/images/info-2.jpg">
<img src="https://www.iut.u-bordeaux.fr/info/assets/images/cours.jpeg">
</div>
<div id="uneDiv">
<p>Images de l'IUT<p>
<div>
<script>
let node=document.getElementById("titre");
console.log(node.nodeType);//1 Element Node
node=document.getElementById("paragraphe1");
console.log(node.nodeType);//1 Element Node
node=document.getElementById("images").firstChild;
console.log(node.nodeType);//3 Text Node (le retour à la ligne)
node=document.getElementById("images").firstElementChild;
console.log(node.nodeType);//1 (la première image)
node=document.getElementById("uneDiv");
console.log(node.nodeType);//1 Element Node
node=document.getElementById("uneDiv").attributes[0];
console.log(node.nodeType);//2 Attribut Node (l'id de la div)
node = document.getElementById("uneDiv").firstChild;
console.log(node.nodeType);//3 Text Node (encore une fois le retour à la ligne)
node = document.getElementById("uneDiv").firstElementChild;
console.log(node.nodeType);//1 Element Node (le paragraphe)
node = document.getElementById("uneDiv").firstElementChild.firstElementChild;
//console.log(node.nodeType);//rien car node vaut null car le text dans le paragraphe n'est pas un element. Cette ligne arrête l'excécution du script
node = document.getElementById("uneDiv").firstElementChild.firstChild;
console.log(node.nodeType);//3 Text Node (ici on a bien le texte dans le paragraphe)
</script>
</body>
</html>
Pensez à bien garder en tête qu'un ELEMENT_NODE
(p, img, ...) est différent d'un TEXT_NODE
(ce qu'il y a dans p, dans h1, ...). Ces objets ont donc des attributs et méthodes différentes.
Si on sait qu'on manipule un nœud de type texte, je vous conseille cette écriture (pour lire ou modifier le contenu d'un nœud de type texte)
let valeur=document.getElementById("titre").textContent;
console.log(valeur); // le texte "Titre"
document.getElementById("titre").textContent = "Le titre a changé";
Méthodes d'accès aux nœuds
Nous avons vu document.getElementById()
. Il en existe beaucoup. Dans le cadre de ce cours, il faut principalement connaitre celles listées ci-dessous. Je vous laisse lire les exemples de la documentation et les exemples (interactifs) de la MDN.
Une erreur courante des étudiants est de confondre le type de ce qui est retourné par ces méthodes.
getElementById
retourne un seul élémentgetElementsByTagName
retourne uneHTMLCollection
querySelectorAll
retourne uneNodeListe
(sur laquelle on va généralement itérer).- documentation de
HTMLCollection
- documentation de
NodeList
Modifications du DOM
Il existe un grand nombre de méthodes permettant, en JS, de créer, modifier, copier, supprimer, déplacer des nœuds dans l'arborescence du DOM.
Dans le cadre de ce cours, il faut principalement connaitre celles listées ci-dessous. Je vous laisse lire les exemples de la documentation et les exemples (interactifs) de la MDN.
Se déplacer dans le DOM
Le DOM étant un arbre, l'API fournit des méthodes permettant de se déplacer dans le DOM à partir d'un nœud.
Encore une fois, il en existe plein. Dans le cadre de ce cours, il faut principalement connaitre celles listées ci-dessous. Je vous laisse lire les exemples de la documentation et les exemples (interactifs) de la MDN.
- parentNode
- previousSibling et nextSibling
- childNodes : attention retourne une
NodeList
, qu'on va certainement avoir envie de parcourir
Différence entre nodeValue
et value
et textContent
La différence entre value
et nodeValue
réside dans leur utilisation et le type d'éléments DOM sur lesquels ils agissent.
-
value
:value
est une propriété spécifique pour les éléments de formulaire tels que les inputs, les textareas, etc.- Elle permet de définir ou d'obtenir la valeur actuelle de l'élément de formulaire.
-
textContent
:textContent
est une propriété spécifique aux nœuds DOM qui représentent des éléments (comme<div>
,<p>
,<span>
, etc.).- Cette propriété renvoie le contenu textuel de l'élément et de tous ses descendants sous forme de texte brut.
- Elle est utilisée pour récupérer ou définir le contenu textuel visible d'un élément, en ignorant tout balisage HTML présent à l'intérieur.
-
nodeValue
:-
nodeValue
est une propriété générale pour tous les nœuds DOM, pas seulement les éléments de formulaire. -
Elle permet d'accéder ou de définir la valeur du nœud DOM, qui peut être du texte, des commentaires, etc.
-
Bien que ce soit tout à fait valide, on évitera (en S2) d'utiliser nodeValue
.
On préfèrera :
value
pour les formulairestextcontent
pour<div>
,<p>
,<span>
, ...
<p> Ci-dessous un <span> truc </span> à remplir.</p>
<form>
<label for="nom">Nom :</label>
<input id="nom" type="text" name="nom"><br><br>
<label for="mail">Email :</label>
<input id="mail" type="email" name="mail"><br><br>
<label for="date">Date :</label>
<input id="date" type="date" name="date"><br><br>
</form>
<script>
const nodeNom = document.getElementById("nom");
const nodeMail = document.getElementById("mail");
const nodeDate = document.getElementById("date");
console.log(`Nom : ${nodeNom.value}`); //ok
console.log(`Nom : ${nodeNom.nodeValue}`); //not ok
nodeMail.value = "journet@labri.fr" //ok
nodeDate.value = "2024-02-13";
console.log(nodeDate.value); //ok
const nodeSpan = document.getElementsByTagName("span")[0].firstChild;;
console.log(`Texte dans le span ${nodeSpan.value}`);//not ok
console.log(`Texte dans le span ${nodeSpan.nodeValue}`);//ok mais pas pratique (il a fallu faire le firstChild)
nodeSpan.nodeValue = "formulaire (via nodeValue)";
//on préfèrera
const nodeSpan2 = document.getElementsByTagName("span")[0];
console.log(`Texte dans le span ${nodeSpan2.texcontent}`);// ok et plus pratique
nodeSpan2.textContent = "formulaire (via textContent)";
</script>
Exercice
Le code ci-dessous, génère ce rendu.
<html>
<head>
<title>Exercices</title>
<style>
.red-border {
border: 2px solid red;
}
</style>
</head>
<body>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<p><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/c/c5/Gustave_Courbet_-_The_Trout_-_WGA05474.jpg/220px-Gustave_Courbet_-_The_Trout_-_WGA05474.jpg" alt="Courbet peinture"> </p>
<p id="legende"> </p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation supprimer laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<script>
</script>
</body>
</html>
Comme on le voit sur l'image ci-dessous, il est possible d'ajouter du code js
qui réalise les transformations suivantes :