Vous êtes sur la page 1sur 104

Arbre DOM

JavaScript

L'arbre DOM

 L’épine dorsale d’un document HTML est constituée de balises.


 Le DOM represente une page HTML sous format d'arbre
 Selon le modèle d’objets de document (DOM), chaque balise
HTML est un objet.
 Les balises imbriquées sont des “enfants” de celle qui les entoure.
 Tous ces objets sont accessibles via JavaScript, et nous pouvons
les utiliser pour modifier la page.
Arbre DOM
Considérons la page HTML suivante

H & H: Research and Training


Arbre DOM

JavaScript

Exemple :

document.body.style.background = 'red';
setTimeout(() => document.body.style.background =
'white',3000);
Arbre DOM

JavaScript

Exemple :

document.body.style.background = 'red';
setTimeout(() => document.body.style.background =
'white',3000);

Nous avons utilisé style.background pour changer la couleur


d’arrière-plan de document.body, Mais il existe de nombreuses
autres propriétés, telles que :
- innerHTML – Contenu HTML d'un élément.
- textHTML – Texte d'un élément
- … etc.
Arbre DOM

Un exemple du DOM

<!DOCTYPE html>
<html lang="fr">
<head>
<title>My JS Page</title>
</head>
<body>
Hello world!
</body>
</html>
Le DOM représente le HTML comme une structure arborescente de balises ce qui donne:
Arbre DOM

JavaScript

Explication

 Les balises sont des nœuds/éléments et forment la structure


arborescente ou <html> est à la racine, puis <head> et <body>
sont ses enfants, etc.
 Le texte à l’intérieur des éléments forme des nœuds texte,
étiquetés comme #text :
- Un nœud texte ne contient qu’une chaîne de caractères.
- Il est toujours une feuille de l'arbre.
- On peut avoir des nœuds de texte qui font partie du DOM et qui
ne contiennent que des espaces et des retours à la ligne
Arbre DOM

JavaScript

Voici des nœuds sans espaces et retour à la ligne


<!DOCTYPE html>
<html><head> <title>Document</title></head><body>Hello </body></html>

Donne
Arbre DOM

JavaScript

Auto-correction
 En HTML si le navigateur rencontre du code mal formé, il le corrige
automatiquement lors de la création du DOM.
 Par exemple, la balise la plus haute est toujours <html>.
Même s’elle n’existe pas dans le document, elle existera dans le
DOM, car le navigateur la créera. Il en va de même pour <body>.
Arbre DOM

JavaScript

Par exemple, si le fichier HTML est le seul mot "Hello", le navigateur


l’enroulera dans <html> et <body>, et ajoutera le <head> requis, et
le DOM sera :

Lors de la création du DOM, les navigateurs traitent automatiquement


les erreurs dans le document, ferment les balises, etc

http://software.hixie.ch/utilities/js/live-dom-viewer/
Parcourir le DOM

JavaScript

Parcourir le DOM
 Le DOM nous permet de faire n’importe quoi avec les éléments et
leur contenu, mais nous devons d’abord atteindre l’objet DOM
correspondant.
 Toutes opérations sur DOM commencent par l’objet document.
C’est le “point d’entrée” principal du DOM. De là, nous pouvons
accéder à n’importe quel nœud.
Parcourir le DOM

JavaScript
Voici une image des liens qui permettent de naviguer entre les nœuds
DOM :
Parcourir le DOM

JavaScript

Le nœud de document le plus haut est document.documentElement.


C’est le noeud DOM de la balise <html>.

<html> = document.documentElement

Les nœuds supérieurs de l’arbre sont disponibles directement en tant


que propriétés de document

Pour accéder au "body"


<body> = document.body

Pour accéder au "head"


<head> = document.head
Parcourir le DOM

JavaScript
Astuce
 Un script ne peut pas accéder à un élément qui n’existe pas au
moment de l’exécution
 En particulier, si un script se trouve dans le <head>, alors
document.body n’est pas disponible, car le navigateur ne l’a pas
encore lu.

Pour accéder au "body"


<!DOCTYPE html>
<html lang="fr">
<head>
<title>My JS Page</title>
<script> console.log(document.body);</script>
</head>
<body>
Hello world !!!
</body>
</html>

Dans le DOM, la valeur null signifie "n'existe pas"


Parcourir le DOM

JavaScript

Enfants : childNodes, firstChild, lastChild


Nous utiliserons désormais deux termes :
 Noeuds enfants (ou enfants) – éléments qui sont des enfants
directs d'un noeuds. Par exemple, <head> et <body> sont des
enfants de l’élément<html>.
 Descendants – tous les éléments imbriqués dans l’élément
donné, y compris les enfants, leurs enfants, etc.
Parcourir le DOM

JavaScript

Par exemple, ici <body> a des enfants <div> et <ul> (et quelques noeuds
texte vides) :
<html lang="fr">
<body>
< div > Begin </div>
< ul>
< li>
< b > Information < /b >
< /li >
< /ul >
</body>
</html>

...Et les descendants de <body> ne sont pas seulement les enfants


directs <div> et <ul> mais aussi les éléments imbriqués, tels que <li> (un
enfant de <ul> ) et <b> (un enfant de <li>)
Comment peut on explorer les enfants de body ?
Parcourir le DOM

JavaScript

Récupérer tous les enfants (élément, texte ou autre) d’un élément


HTML
var enfants = document.body.childNodes;
for(let enfant of enfants)
console.log(enfant);

Résultat :
Parcourir le DOM

JavaScript

Récupérer tous les éléments (balises) enfants d’un élément HTML


var enfants = document.body.children;
for(let enfant of enfants)
console.log(enfant);

Résultat :
Parcourir le DOM

JavaScript

<body>
< div > Begin </div>
< ul>
< li>
< b > Information < /b >
< /li >
< /ul >
< script >
for (let i = 0; i < document.body.childNodes.length; i++) {
alert( document.body.childNodes[i] ); // Text,div,text,ul,text,script
}
...more stuff...
</body>
</html>

Si nous exécutons l’exemple ci-dessus, le dernier élément affiché est


<script>.
Le document peut contenir des choses en dessous, mais au moment de
l’exécution du script, le navigateur ne l’a pas encore lu, donc le script
ne le voit pas.
Parcourir le DOM

JavaScript

Collections DOM

 Comme nous pouvons le voir, childNodes ressemble à un tableau.


 Mais en réalité ce n’est pas un tableau, mais plutôt une [collection]
qui est un objet itérable spécial semblable à un tableau.
 Les collections DOM sont en lecture seule
childNodes[i] = .... opération impossible

 Changer le DOM nécessite d’autres méthodes. Nous les verrons


dans ce qui suit.
Parcourir le DOM

JavaScript

Les collections DOM sont live

 Presque toutes les collections DOM sont live.


 En d’autres termes, elles reflètent l’état actuel du DOM.
 Si nous gardons une référence à element.childNodes, et nous
ajoutons/supprimons des nœuds dans le DOM, alors ils apparaissent
automatiquement dans la collection.
Parcourir le DOM

JavaScript

N’utilisez pas for..in pour parcourir les collections

 Les collections sont itérables en utilisant for..of.


 La boucle for..in parcourt toutes les propriétés énumérables.
 Et les collections ont des propriétés “supplémentaires” rarement
utilisées que nous ne voulons généralement pas obtenir :

<body>
<script>
// affiche 0, 1, length, item, values et plus encore.
for (let prop in document.body.childNodes)
alert(prop);
</script>
</body>
Parcourir le DOM

JavaScript

Récupérer le premier élément (balise) (nom) fils d’un élément HTML

var firstElem = document.body.firstElementChild;


console.log(firstElem.nodeName);
Parcourir le DOM

JavaScript

Récupérer le premier élément (balise) (nom) fils d’un élément HTML

var firstElem = document.body.firstElementChild;


console.log(firstElem.nodeName);

Récupérer le premier fils (élément, texte ou autre) (nom) d’un élément


HTML

var premierFils = document.body.firstChild;


console.log(premierFils.nodeName);
Parcourir le DOM

JavaScript

Récupérer le dernier élément (balise) (nom) fils d’un élément HTML

var dernierFils = document.body.lastElementChild;


console.log(dernierFils.nodeName);
Parcourir le DOM

JavaScript

Récupérer le dernier élément (balise) (nom) fils d’un élément HTML

var dernierFils = document.body.lastElementChild;


console.log(dernierFils.nodeName);

Récupérer le dernier fils (élément, texte ou autre) (nom) d’un élément


HTML

var dernierFils = document.body.lastChild;


console.log(dernierFils.nodeName);
Parcourir le DOM

JavaScript

Frères, sœurs et parent


Les frères et sœurs sont des nœuds qui sont les enfants du même
parent.
Par exemple, ici <head> et <body> sont des frères et sœurs :

<html>
<head>....</head><body>....</body>
</html>

<body> est dit être le frère “suivant” de <head>,


<head> est dit être le frère “précédent” de <body>.
Parcourir le DOM

JavaScript

Frères, sœurs et parent

previousSibling
previousElementSibling
nextSibling
nextElementSibling
Parcourir le DOM

JavaScript

// Le parent de <body> est <html>


alert(document.body.parentNode === document.documentElement);
//true
//Apres <head> vient <body>
alert(document.head.nextSibling);
//HTMLBodyElement

// Avant <body> vient <head>


alert( document.body.previousSibling );
//HTMLHeadElement
Parcourir le DOM

JavaScript

Plus de liens : table


 Jusqu’à présent, nous avons décrit les propriétés de navigation de
base.
 Certains types d’éléments DOM peuvent fournir des propriétés
supplémentaires, spécifiques à leur type, pour plus de commodité.
 Parmis ces éléments on trouve la balise table
Parcourir le DOM

JavaScript

Plus de liens : table

L’élément table supporte (en plus de ce qui précède) ces propriétés :


 table.caption/tHead/tFoot – références aux éléments <caption>,
<thead>, <tfoot>.
 table.tBodies – la collection d’éléments <tbody> (peut être
multiple selon la norme, mais il y en aura toujours au moins une –
même s’elle n’est pas dans le HTML source, le navigateur la
mettra dans leDOM).
<table><thead>, <tfoot>, <tbody> fournissent la propriété rows :
 table.rows – la collection de <tr> à l’intérieur.
 tr.cells – la collection de cellules <td> et <th> à l’intérieur du <tr>
donné.
Parcourir le DOM

JavaScript
Un exemple d’utilisation :

<table id="table" border="1">


<thead>
<tr>
<th>Nom</th>
<th>Prenom</th>
</tr>
</thead>
<tr>
<td>ALAMI</td>
<td>Ahmad</td>
</tr>
</table>
<script>
// obtenir td de "Prenom"
td = table.rows[0].cells[1];
td.style.backgroundColor = "red";
</script>
Parcourir le DOM

JavaScript

Résumé
Étant donné un nœud DOM, nous pouvons aller vers ses voisins
immédiats en utilisant les propriétés de navigation.
Il en existe deux ensembles principaux :
 Pour tous les nœuds : parentNode, childNodes, firstChild,
lastChild, previousSibling, nextSibling.
 Pour les nœuds élément uniquement : parentElement, children,
previousElementSibling, lastElementChild, firstElementChild
nextElementSibling.
Parcourir le DOM

JavaScript
Atelier
Enfants DOM : Regardez cette page

<html>
<body>
<div>one</div>
<ul>
<li>John</li>
<li>Anna</li>
</ul>
</body>
</html>

Pour chacun des éléments suivants, donnez au moins un moyen d’y


accéder :
Le noeud <div> du DOM ?
Le noeud <ul> du DOM ?
Le deuxième <li> (avec Anna) ?
Parcourir le DOM

JavaScript
Solution
EIl existe de nombreuses façons, par exemple :
Le noeud <div> du DOM :
document.body.firstElementChild
document.body.children[0]
document.body.childNodes[1]

Le nœud <ul> du DOM :


document.body.lastElementChild
document.body.children[1]

Le deuxième <li> (avec Anna) :

// obtenir <ul>, puis obtenir son dernier élément enfant


document.body.lastElementChild.lastElementChild
Parcourir le DOM

JavaScript

Atelier

La question des frères et sœurs


Si élément – est un nœud élément arbitraire du DOM …
1- Est-il vrai que elem.lastChild.nextSibling est toujours null ?
2- Est-il vrai que elem.children[0].previousSibling est toujours null ?
Parcourir le DOM

JavaScript

Atelier

La question des frères et sœurs


Si élément – est un nœud élément arbitraire du DOM …
1- Est-il vrai que elem.lastChild.nextSibling est toujours null ?
2- Est-il vrai que elem.children[0].previousSibling est toujours null ?

1 - Oui c’est vrai.


L’élément elem.lastChild est toujours le dernier, il n’a pas de nextSibling.
2 - Non, c’est faux.
elem.children[0] est le premier enfant parmi les éléments. Mais il peut
exister des nœuds non-éléments avant lui. Ainsi, previousSibling peut
être un nœud texte.
Remarque: dans les deux cas, s’il n’y a pas d’enfants, il y aura une
erreur.
getElement*, querySelector*

JavaScript

Recherche : getElement*, querySelector*.

Les propriétés de navigation DOM sont excellentes lorsque les


éléments sont proches les uns des autres. Et s'ils ne le sont
pas ? Comment obtenir un élément arbitraire de la page ?
Il existe des méthodes de recherche supplémentaires pour cela :
- getElement*
- querySelector*
getElement*, querySelector*

JavaScript
document.getElementById ou juste l'id

Si un élément possède l'attribut id, nous pouvons obtenir l'élément à


l'aide de la méthode document.getElementById(id), peu importe où
il se trouve.

<div id="elem">
<div id="elem-content">Element</div>
</div>
<script>
let elem = document.getElementById('elem');
elem.style.background = 'red';
</script>
getElement*, querySelector*

JavaScript
document.getElementById ou juste l'id

Si un élément possède l'attribut id, nous pouvons obtenir l'élément à


l'aide de la méthode document.getElementById(id), peu importe où
il se trouve.

<div id="elem">
<div id="elem-content">Element</div>
</div>
<script>
let elem = document.getElementById('elem');
elem.style.background = 'red';
</script>

Remarque
Il ne faut pas utiliser # dans getElementById().
getElement*, querySelector*

JavaScript

document.getElementById ou juste l'id

Il existe également une variable globale nommée par id qui fait référence
à l'élément, on reprend le même exemple :

<div id="elem">
<div id="elem-content">Element</div>
</div>
<script>
elem.style.background = 'red'
window['elem-content'].style.background='red'
//ou
alert(document.getElementById('elem-content').innerHTML);
</script>
getElement*, querySelector*

JavaScript

document.getElementById ou juste l'id

...sauf si nous déclarons une variable JavaScript portant le même nom,


qui est alors prioritaire

<div id="elem">
<div id="elem-content">Element</div>
</div>
<script>
let elem = 5;
alert(elem); // 5
</script>

En pratique la méthode la plus utilisée et qui est aussi préférable est


document.getElementById.
getElement*, querySelector*

JavaScript

document.getElementById()

 La méthode getElementById ne peut être appelée que sur l'objet


document. Elle recherche l'identifiant donné dans l'ensemble du
document.
 Seulement document.getElementById, pas elem.getElementById
getElement*, querySelector*

JavaScript

L'id doit être unique.


 L'id doit être unique. Il ne peut y avoir qu'un seul élément dans
le document avec l'id donné.
 S'il y a plusieurs éléments avec le même id, le comportement
des méthodes qui l'utilisent est imprévisible, par exemple:
document.getElementById renvoi le premier élément trouvé.
 Il faut donc respecter la règle et garder l'id unique.
getElement*, querySelector*

JavaScript

getElementsBy*

 Il existe également d'autres méthodes pour rechercher des nœuds


par une balise, une classe, ou par le nom.
- elem.getElementsByTagName(tag) recherche les éléments
avec le tag donné et retourne la collection de ceux-ci. Le paramètre
tag peut également être une étoile "*" pour "toutes les
balises".
- elem.getElementsByClassName(class) renvoie les éléments
qui ont la classe CSS donnée.
- elem.getElementsByName(name) renvoie les éléments ayant
l'attribut name donné, dans tout le document.
getElement*, querySelector*

JavaScript
elem.getElementsByTagName(tag)

Trouvons toutes les balises 'input' dans la table


<table id="table">
<tr>
<td>Your age:</td>
<td>
<input type="radio" name="age" value="young" checked> less than 18
<input type="radio" name="age" value="mature"> from 18 to 50
<input type="radio" name="age" value="senior"> more than 50
</td>
</tr>
</table>
<script>
let inputs = table.getElementsByTagName('input');
for (let input of inputs) {
alert(input.value + ': ' + input.checked);
}
</script>
getElement*, querySelector*

JavaScript

getElementsByTagName() renvoie une collection, pas un élément :

// doesn't work
console.log(document.getElementsByTagName('input').value);

Ce qu'il faut faire c'est :

// should work (if there's an input)


console.log(document.getElementsByTagName('input')[0].value);

Ou
// should work (if there's an input)
let inputs = document.getElementsByTagName('input');
for(let input of inputs){
console.log(input.value)
}
getElement*, querySelector*

JavaScript

elm.getElementsByClassName() & elm.getElementsByName()

Chercher les éléments avec la classe "article" à l'interieur du form

<form name="my-form">
<div class="article">Article</div>
<div class="long article">Long article</div>
</form>
<script>
// find by name attribute
let form = document.getElementsByName('my-form')[0];

// find by class inside the form


let articles = form.getElementsByClassName('article');
alert(articles.length);
</script>
getElement*, querySelector*

JavaScript
getElementsBy*
Toutes les méthodes "getElementsBy*" renvoient une collection live.
Ce type de collections reflètent toujours l'état actuel du document et se
mettent à jour automatiquement lorsqu'il est modifié.

<div>First div</div>

<script>
let divs = document.getElementsByTagName('div');
alert(divs.length); // 1
</script>

<div>Second div</div>

<script>
alert(divs.length); // 2
</script>
getElement*, querySelector*

JavaScript
elem.querySelector(css)

Cette méthode renvoie les éléments de elem correspondant au sélecteur


CSS donné
Ici, nous recherchons le premier <li> qui est le dernier enfant de <ul> :
<ul>
<li>The</li>
<li>test</li>
</ul>
<ul>
<li>has</li>
<li>passed</li>
</ul>
<script>
let element = document.querySelector('ul > li:last-child');
alert(element.innerHTML);
</script>
getElement*, querySelector*

JavaScript
elem.querySelectorAll(css)
Cette méthode renvoie tous les éléments de elem correspondant au
sélecteur CSS donné
Ici, nous recherchons tous les éléments <li> qui sont les derniers
enfants:
<ul>
<li>The</li>
<li>test</li>
</ul>
<ul>
<li>has</li>
<li>passed</li>
</ul>
<script>
let elements = document.querySelectorAll('ul > li:last-child');
for (let elem of elements) {
alert(elem.innerHTML);
}
</script>
getElement*, querySelector*

JavaScript

elem.querySelector(css)
 L'appel à elem.querySelector(css) renvoie le premier élément
pourle sélecteur CSS donné.
 En d'autres termes, le résultat est le même que celui de
elem.querySelectorAll(css)[0], mais ce dernier recherche tous
leséléments et en choisit un, alors que elem.querySelector
n'en recherche qu'un.
 C'est donc plus rapide et aussi plus court à écrire.
getElement*, querySelector*

JavaScript
querySelectorAll
En revanche, querySelectorAll renvoie une collection statique. C'est
comme un tableau fixe d'éléments.

Si nous l'utilisons à la place, les deux scripts produisent 1 :


<div>First div</div>

<script>
let divs = document.querySelectorAll('div');
alert(divs.length); // 1
</script>

<div>Second div</div>

<script> alert(divs.length); // 1
</script>
getElement*, querySelector*

JavaScript

Résumé
Il existe 6 méthodes principales pour rechercher des noeuds dans
le DOM :
Propriétés de nœud : type, balise et contenu

JavaScript

Classes de nœud DOM


 Les nœuds du DOM peuvent avoir des propriétés différentes
 Par exemple, un nœud correspondant à la balise <a> a des
propriétés liées au lien, et celui correspondant à <input> a des
propriétés liées à l'entrée et ainsi de suite....
 Chaque nœud DOM appartient une classe DOM prédéfinie
 La racine de la hiérarchie est EventTarget, qui est héritée par
Node, et les autres nœuds DOM en héritent.
Propriétés de nœud : type, balise et contenu

JavaScript
Propriétés de nœud : type, balise et contenu

JavaScript
Classes de nœud DOM

 EventTarget : Classe "abstraite" racine. Les objets de cette classe


ne sont jamais créés. C'est la classe de base de tous les nœuds du
DOM supportant ainsi ce que l'on appelle les "événements".
 Node :classe "abstraite", servant de base aux nœuds DOM.
Elle fournit les fonctionnalités : parentNode, nextSibling, childNodes
(qui sont des getters). De même les objets de Node ne sont jamais
créés
 Element : c'est la
classe qui fournit une navigation au niveau des
éléments comme nextElementSibling, children et des méthodes de
recherche comme getElementsByTagName, querySelector
 HTMLElement : est finalement la classe de base pour tous les éléments
HTML. Elle est héritée par les éléments HTML concrets :
HTMLBodyElement, HTMLInputElement, HTMLDivElement ....
Propriétés de nœud : type, balise et contenu

JavaScript
classe d'un noeud DOM

Pour voir le nom de la classe du noeud DOM, il faut se rappeler qu'un objet
JS à la propriété constructor qui référence au constructeur de la classe,
et constructor.name est son nom:

alert( document.body.constructor.name ); //HTMLBodyElement


//ou
alert( document.body ); // [object HTMLBodyElement]

On peut également utiliser instanceof pour vérifier l'héritage :

alert( document.body instanceof HTMLBodyElement ); // true


alert( document.body instanceof HTMLElement ); // true
alert( document.body instanceof Element ); // true
alert( document.body instanceof Node ); // true
alert( document.body instanceof EventTarget ); // true
Propriétés de nœud : type, balise et contenu

JavaScript
Balise : nodeName et tagName

Étant donné un nœud DOM, nous pouvons lire son nom de balise dans
les propriétés nodeName ou tagName, comme :

alert( document.body.nodeName ); // BODY


alert( document.body.tagName ); // BODY
Propriétés de nœud : type, balise et contenu

JavaScript
nodeName et tagName

Étant donné un nœud DOM, nous pouvons lire son nom de balise dans
les propriétés nodeName ou tagName, comme :

alert( document.body.nodeName ); // BODY


alert( document.body.tagName ); // BODY

Y a-t-il une différence entre tagName et nodeName ?


La différence se reflète dans leurs noms :
 La propriété tagName existe uniquement pour les nœuds Element.
 Le nodeName est défini pour tout Node :
- pour les éléments, cela signifie la même chose que tagName.
- pour les autres types de nœuds (texte, commentaire, etc.), il a une
chaîne de caractères avec le type de nœud
Propriétés de nœud : type, balise et contenu

JavaScript
innerHTML: les contenus

La propriété innerHTML permet d’obtenir le HTML à l’intérieur de l’élément


sous forme de chaîne de caractères.
Ce contenu est modifiable. C’est donc l’un des moyens les plus puissants
de modifier la page.
L’exemple montre le contenu de document.body puis le remplace
complètement :

<body>
<p>A paragraph</p>
<div>A div</div>
<script>
alert( document.body.innerHTML );
document.body.innerHTML = 'The new BODY!';
</script>
</body>
Propriétés de nœud : type, balise et contenu

JavaScript
innerHTML: les contenus

Nous pouvons essayer d’insérer du code HTML invalide, le navigateur


corrigera nos erreurs :

<body>
...
<script>
document.body.innerHTML = '<b>test';
alert( document.body.innerHTML );
</script>
</body>

Les scripts ne s’exécutent pas !!


Si innerHTML insère une balise <script> dans le document – elle devient
une partie du HTML, mais ne s’exécute pas.
Propriétés de nœud : type, balise et contenu

JavaScript

nodeValue/data : contenu du nœud texte

La propriété innerHTML n’est valide que pour les nœuds textes.


Ce type de nœuds ont les propriétés : data et nodeValue
Les deux donnent le même résultat, ainsi nous utiliserons data, car
elle est plus courte.
<body>
Hello <!-- Commentaire -->
<script>
let text = document.body.firstChild;
alert(text.data);
let comment = text.nextSibling;
alert(comment.data);
</script>
</body>
Propriétés de nœud : type, balise et contenu

JavaScript
textContent: texte pur

Le textContent donne accès au texte à l’intérieur de l’élément : juste le


texte, moins tous les <tags>.
Par exemple :

<div id="news">
<h1> Headline! </h1>
<p> news and actuality! </p>
</div>
<script>
alert(news.textContent);
</script>

En effet le textContent est beaucoup plus utiliser, pour écrire du texte.


Propriétés de nœud : type, balise et contenu

JavaScript
innertHTML vs textContent

Comparant les deux :

<div id="elem1"></div>
<div id="elem2"></div>
<script>
let name = prompt("What's your name?", "<b>John!</b>");
elem1.innerHTML = name;
elem2.textContent = name;
</script>

Dans la plupart des cas, nous attendons le texte d’un utilisateur et


souhaitons le traiter comme du texte.
Nous ne voulons pas de HTML inattendu sur notre site. Une affectation à
textContent fait exactement cela.
Propriétés de nœud : type, balise et contenu

JavaScript
La propriété "hidden"

hidden et la propriété DOM specifiant si l’élément est visible ou non.


Nous pouvons l’utiliser dans le HTML ou l’attribuer en utilisant JS :

<div>Both divs below are hidden</div>


<div hidden>With the attribute "hidden"</div>
<div id='elem'>JS assigned the property "hidden"</div>
<script>
elem.hidden = true;
</script>

Techniquement, hidden fonctionne de la même manière que :


style="display:none".
Mais c’est plus court à écrire.
Propriétés de nœud : type, balise et contenu

JavaScript

Plus de propriétés
Les éléments DOM ont également des propriétés supplémentaires :
 value : la valeur pour <input>, <select> et <textarea> .
 href : le “href” pour <a href="...">
 id : la valeur de l’attribut “id”, pour tous les éléments (HTMLElement).
 La plupart des attributs HTML ont la propriété DOM correspondante, et
nous pouvons y accéder directement.

Par exemple :

<input type="text" id="elem" value="value">


<script>
alert(elem.type); // "text"
alert(
alert(elem.value); // value
</script>
Propriétés de nœud : type, balise et contenu

JavaScript
Résumé
 Chaque nœud DOM appartient à une certaine classe.
 Les classes forment une hiérarchie.
 L’ensemble des propriétés et des méthodes d'un composant résulte de
l’héritage.
 Les propriétés principales du nœud DOM sont :
- nodeName/tagName : Pour les éléments, nom de balise. Pour les
nœuds non-élément, nodeName décrit ce que c’est. Lecture seulement.
- innerHTML : Le contenu HTML de l’élément. Peut être modifié.
- nodeValue/data : Le contenu d’un nœud non élément (texte,
commentaire). Peut être modifié.
- textContent : Texte à l’intérieur de l’élément : [HTML - <tags>]
Écrit le texte dans l'élément avec les balises et les caractères spéciaux.
 De manière générale la plupart des attributs HTML standard ont une
propriété DOM correspondante.
Attributs et propriétés

JavaScript
Attributs HTML
 En HTML, les balises ont des attributs. Lorsque le navigateur analyse le
code HTML pour créer des objets DOM pour les balises, il reconnaît les
attributs * standard * et crée des propriétés DOM à partir d’elles.
 Ainsi, lorsqu’un élément a id ou un autre attribut standard, la propriété
correspondante est créée. Mais cela ne se produit pas si l’attribut n’est
pas standard.

Par exemple :

<body id="test" something="non-standard">


<script>
alert(document.body.id+"\n"
+document.body.something);
<script>
</body>

Noter qu’un attribut standard pour un élément peut être inconnu pour un
autre. Par exemple,
Attributs et propriétés

JavaScript

Noter qu’un attribut standard pour un élément peut être inconnu pour un
autre.
Par exemple, "type" est standard pour <input> (HTMLInputElement), mais
pas pour <body> (HTMLBodyElement).
Exemple :
<body id="body" type="...">
<input id="input" type="text">
<script>
alert(input.type);
alert(body.type);
</script>
</body>

Donc, si un attribut n’est pas standard, il n’y aura pas de propriété DOM
pour lui. Existe-t-il un moyen d’accéder à ces attributs ?
Attributs et propriétés

JavaScript

Attributs HTML
Tous les attributs sont accessibles en utilisant les méthodes suivantes :
 elem.hasAttribute(name): vérifie l’existence.
 elem.getAttribute(name): obtient la valeur.
 elem.setAttribute(name, value): définit la valeur.
 elem.removeAttribute(name): supprime l’attribut.

Voici une démonstration de la lecture d’une propriété non standard :


<body something = "non-standard">
<script>
alert(document.body.getAttribute('something'));
</script>
</body>
Attributs et propriétés

JavaScript

Attributs HTML
Les attributs HTML présentent les caractéristiques suivantes :
 Leur nom est insensible à la casse (id est identique à ID).
 Leurs valeurs sont toujours des chaînes de caractères.

Voici une démonstration détaillée de l’utilisation des attributs :


<body>
<div id="elem" about="Elephant"></div>
<script>
alert(elem.getAttribute('About') );
elem.setAttribute('Test', 123);
alert(document.body.firstElementChild.getAttribute('Test'));
for (let attr of elem.attributes) {
alert( `${attr.name} = ${attr.value}` );
}
</script>
</body>
Attributs et propriétés

JavaScript

Utilité des attributs non standard, dataset

Parfois, des attributs non standard sont utilisés pour transmettre des
données personnalisées de HTML à JavaScript

<div show-info="name"></div>
<div show-info="age"></div>
<script>
let user = {
name: "Anna",
age: 25
};
for(let div of document.querySelectorAll('[show-info]')) {
let field = div.getAttribute('show-info');
div.innerHTML = user[field];
}
</script>
Attributs et propriétés

JavaScript

Utilité des attributs non standard, dataset


Ils peuvent également être utilisés pour ajouter du style css à un
élément. Par exemple, ici order-state est utilisé pour changer l'etat
d'une commande :
<style>
.order[order-state="new"] { color: green; }
.order[order-state="pending"] { color: blue; }
.order[order-state="canceled"] { color: red; }
</style>
<div class="order" order-state="new"> A new order.</div>
<div class="order" order-state="pending"> A pending order.</div>
<div class="order" order-state="canceled"> A canceled order.</div>
Attributs et propriétés

JavaScript

Utilité des attributs non standard, dataset


Ils peuvent également être utilisés pour ajouter du style css à un
élément. Par exemple, ici order-state est utilisé pour changer l'etat
d'une commande :
<style>
.order[order-state="new"] { color: green; }
.order[order-state="pending"] { color: blue; }
.order[order-state="canceled"] { color: red; }
</style>
<div class="order" order-state="new"> A new order.</div>
<div class="order" order-state="pending"> A pending order.</div>
<div class="order" order-state="canceled"> A canceled order.</div>

L'utilisation d'un attribut est préférable à l'utilisation de classes telles


que .order-state-new, .order-state-pending, .order-state-canceled, vue
qu'un attribut est plus facile à gérer.

div.setAttribute('order-state', 'canceled');
Attributs et propriétés

JavaScript

Les attributs non standard & dataset


 Le langage HTML est vivant, il grandit et de plus en plus.

 Ainsi un attribut non standard peut plus tard être introduit et devenir
standard chose qui peut avoir des effets inattendus
 Pour éviter les conflits, il existe les attributs data-*
 Tous les attributs commençant par “data-” sont réservés à l’usage
des programmeurs. Ils sont disponibles dans la propriété dataset.
 Par exemple, si un elem a un attribut nommé "data-about", il est
disponible en tant que elem.dataset.about.

Exemple
<body data-about = "Elephants">
<script>
alert(document.body.dataset.about);
</script>
Attributs et propriétés

JavaScript
Utilité des attributs non standard, dataset
Reprenant l'exemple des commandes :

<style>
.order[data-order-state="new"] { color: green; }
.order[data-order-state="pending"] { color: blue; }
.order[data-order-state="cancel"] { color: red; }
</style>
<div class="order" data-order-state="new">
A new order.
</div>
<script>
alert(order.dataset.orderState);
order.dataset.orderState = "pending";
</script>
Attributs et propriétés

JavaScript
Utilité des attributs non standard, dataset
Reprenant l'exemple des commandes :

<style>
.order[data-order-state="new"] { color: green; }
.order[data-order-state="pending"] { color: blue; }
.order[data-order-state="cancel"] { color: red; }
</style>
<div class="order" data-order-state="new">
A new order.
</div>
<script>
alert(order.dataset.orderState);
order.dataset.orderState = "pending";
</script>

Les attributs data-* est un moyen valide et sûr de transmettre des


données personnalisées.
Les dataset sont modifiable, ainsi tout code CSS met à jour la vue en
conséquence.
Attributs et propriétés

JavaScript

Résumé
 Les attributs – sont ce qui est écrit en HTML.

 Les propriétés – sont ce qui se trouve dans les objets DOM.

 Le nom des propriétés est sensible à la casse celui des attributs non

 Les méthodes des attributs sont les suivantes :


elem.hasAttribute(name): vérifie l’existence.
elem.getAttribute(name): obtient la valeur.
elem.setAttribute(name, value): définit la valeur.
elem.removeAttribute(name): supprime l’attribut.
 Il est préférable d’utilisation les propriétés DOM .

 On peut utiliser les attributs standard comme nous pouvons ajouter


nos propres attributs non-standard, ces derniers peuvent être ajouter
de manière simple comme nous pouvons utiliser les datasets
Attributs et propriétés

JavaScript

Atelier

Écrivez le code pour sélectionner l’élément avec l’attribut data-widget-name


dans le document et pour lire sa valeur.

<!DOCTYPE html>
<html>
<body>
<div data-widget-name="menu">Choose the genre</div>
<script>
/* your code */
</script>
</body>
</html>
Attributs et propriétés

JavaScript

Solution
<!DOCTYPE html>
<html>
<body>
<div data-widget-name="menu">Choose the genre</div>
<script>
let elem = document.querySelector('[data-widget-name]');
console.log(elem.dataset.widgetName);
//or
console.log(elem.getAttribute('data-widget-name'));
</script>
</body>
</html>
Styles et classes

JavaScript

Styles et classes
En CSS Il y a, en général, deux façons de stylé un élément :
 Créer une classe dans CSS et l’ajouter: <div class="...">
 Écrire les propriétés directement dans style: <div style="...">.

JavaScript peut modifier les classes et les propriétés de style.


Styles et classes

JavaScript
className et classList
Changer une classe est l’une des actions les plus utilisées dans les
scripts.
Pour les classes, la propriété class ne peut être utilisé vue qu'elle
est réservé au langage mais à la place on a "className".

Par exemple :
<body class="page d'accueil">
<script>
alert(document.body.className);
</script>
</body>

Si nous attribuons quelque chose à elem.className, elle remplace la


chaîne entière de classes.
Styles et classes

JavaScript

className et classList

Pour ajouter ou enlever une classe on utilise la propriete classList


classList est un objet spécial avec des méthodes pour add / remove /
toggle une seule classe.
Par exemple :

<body class="page d'accueil">


<script>
document.body.classList.add('article');
alert(document.body.className);
</script>
</body>
Styles et classes

JavaScript

className et classList
En terme de classe nous pouvons opérer à la fois :
 sur la chaîne de classe complète en utilisant className
 ou sur des classes individuelles en utilisant classList

Les méthodes de classList :


 elem.classList.add/remove("class") : ajoute/supprime la classe.
 elem.classList.toggle("class") : ajoute la classe si elle n'existe
pas, sinon la supprime.
 elem.classList.contains("class") : Vérifie la présence de la classe
donnée, renvoie true/false
Styles et classes

JavaScript

classList

Par ailleurs, classList est itérable, nous pouvons donc lister toutes
les classes avec for..of, comme ceci :

<body class="main page">


<script>
for (let name of document.body.classList) {
alert(name);
}
</script>
</body>
Styles et classes

JavaScript

Style de l’élément

La propriété style est un objet qui correspond au "style".

Modifiant la couleur d'un élément

var container = document.getElementById("container");


container.style.color = "red";

Pour les propriétés CSS composées de deux mots séparés par -, il


faut supprimer - mettre la propriété en camelCase

var container = document.getElementById("container");


container.style.backgroundColor = "red";
Styles et classes

JavaScript

Style de l’élément

Parfois nous voulons attribuer une propriété de style, et ensuite la


retirer.

Prenant l'exemple suivant :


document.body.style.display = "none";
setTimeout(() => document.body.style.display = "",1000);

En donnant une chaine vide à style.display, le navigateur applique les


classes CSS et ses styles intégrés normalement, comme s’il n’y avait
pas de propriété style.display.
Styles et classes

JavaScript
Réécriture complète avec style.cssText
style.* est utilisé pour attribuer des propriétés destyle individuelles.
Nous ne pouvons pas attribuer le style complet comme :
div.style =
Ainsi pour définir un style complet comme une chaîne, il y a une
propriété spéciale style.cssText :

<div id="div">Bouton</div>
<script>
div.style.cssText =`color:red;
background-color: yellow;
width: 100px;
text-align: center;`;
alert(div.style.cssText);
</script>

Attention !! cette propriété enlève tous les styles pré-existants: au


lieu d’être ajoutée, elle les remplace.
Styles et classes

JavaScript

Résumé
Pour gérer les classes, il y a deux propriétés DOM :
 className: la valeur de chaîne, utile pour gérer l’ensemble complet
des classes.
 classList: l’object avec les méthodes add/remove/toggle/contains,
utile pour manipuler les classes individuelles.
Pour changer les styles :
 La propriété style est un objet avec les styles en camelCase.

 La propriété style.cssText correspond à l’attribut entier de "style",


la chaîne complète des styles, elle est en mode lecture & écriture
Modification du document

JavaScript

Modification du document

La modification DOM est la clé pour créer des pages “live”.


Ainsi nous pouvons modifier à la volée” le contenu de la page existante.
Les étapes à suivre sont :
 Créer l’element
 Préparer ses attributs [ et valeurs ]
 L’ajouter au document
Modification du document

JavaScript

Exemple : afficher un message


<style>
.alert {
padding: 15px;
border: 1px solid #d6e9c6;
border-radius: 4px;
color: #3c763d;
background-color: #dff0d8;
}
</style>
<div class="alert">
<strong>Hi there!</strong> You've read an important message.
</div>

C’était un exemple HTML. Créons maintenant la même div avec


JavaScript (en supposant que les styles sont déjà dans le HTML ou
un fichier CSS externe).
Modification du document

JavaScript

Création d’un élément

Pour créer des nœuds DOM, il existe deux méthodes :


document.createElement(tag)
document.createTextNode( text );

Crée un nouveau noeud élément avec la balise donnée :

let div = document.createElement('div');

Crée un nouveau nœud texte avec le texte donné :

let textNode = document.createTextNode('Here I am');


Modification du document

JavaScript

Création du message

La création du message div prend 3 étapes :

let div = document.createElement('div');


div.className = "alert";
div.innerHTML = "<strong>Hi there!</strong> You've read an
important message.";

Nous avons créé l’élément. Mais pour le moment, ce n’est que dans
une variable nommée div, pas encore dans la page.

Nous ne pouvons donc pas le voir.


Modification du document

JavaScript
Méthodes d’insertion
Pour faire apparaître la div, nous devons l’insérer dans document.
Le méthode d'insertion est append : document.body.append(div).
<style>
.alert {
padding: 15px;
border: 1px solid #d6e9c6;
border-radius: 4px;
color: #3c763d;
background-color: #dff0d8;
}
</style>
<body>
<script>
let div = document.createElement('div');
div.className = "alert";
div.innerHTML = "<strong>Hi there!</strong> Important message.";
document.body.append(div);
</script>
</body>
Modification du document

JavaScript
Modification du document
Afin d'insérer un élément dans un document HTML, on trouve plusieurs
méthodes d’insertion, elles spécifient différents endroits où insérer :
 node.append(...nodes or string):ajouter des nœuds ou des
chaînes de caractères à la fin du contenu du node (fils).
 node.prepend(...nodes or string):insérer des nœuds ou des
chaînes de caractères au début du contenu du node (fils).
 node.before(...nodes or string):insérer des nœuds ou des
chaînes de caractères avant node (frere),
 node.after(...nodes or string):insérer des nœuds ou des
chaînes de caractères après node (frere),
 node.replaceWith(...nodes or string):remplace node avec
les nœuds ou chaînes de caractères donnés.
Les arguments de ces méthodes sont une liste arbitraire de nœuds DOM
à insérer ou des chaînes de texte (qui deviennent automatiquement des
nœuds de texte).
Modification du document

JavaScript

Voici un exemple d’utilisation de ces méthodes pour ajouter des


éléments à une liste et le texte avant/après :

<ol id = "ol">
<li> 0 </li>
<li> 1 </li>
<li> 2 </li>
</ol>
<script>
ol.before( b' efore )
';
' fter )
ol.after( a ';
let liFirst = document.createElement("li");
liFirst.innerHTML = "prepend";
ol.prepend(liFirst);
let liLast = document.createElement("li");
liLast.innerHTML = "append";
ol.append(liLast);
</script>
Modification du document

JavaScript

Ces méthodes peuvent insérer plusieurs nœudset morceaux de texte


en un seul appel.

Par exemple, ici une chaîne de caractères et un élément sont insérés :

<div id = "div"> </div>


<script>
div.before("<p>Hello</p>",document.createElement("hr" ));
</script>

Remarque: le texte est inséré “en tant que texte”, pas “en tant que
HTML”
Modification du document

JavaScript

insertAdjacentHTML/Text/Element
Pour insérer des éléments HTML on peut utiliser la méthode :
elem.insertAdjacentHTML(where, html).
Le premier paramètre est un mot de code, spécifiant où insérer par rapport
à elem et doit être l’un des suivants ::
 "beforebegin":insère html immédiatement avant elem.
 "afterbegin":insère html dans elem, au début
 "beforeend":insère html dans elem, à la fin,
 "afterend": insère html immédiatement après elem.

Le second paramètre est une chaîne HTML insérée “au format HTML”.
Modification du document

JavaScript

Exemple

<div id = "div"> </div>


<script>
'
div.insertAdjacentHTML( beforebegin ' <p>Hello</p>
, ' '
);
div.insertAdjacentHTML('afterend', '<p>Bye</p>');
</script>

Rendu

<p> Hello </p>


<div id="div"></div>
<p> Bye </p>
Modification du document

JavaScript

insertAdjacentHTML/Text/Element

insertAdjacentHTML(where, html) a deux sœurs :


 elem.insertAdjacentText(where,text): la même syntaxe, mais
un texte est insérée en tant que chaîne de caractères au lieu d'HTML.
 elem.insertAdjacentElement(where,elem):la même syntaxe,
mais insère un élément.
En pratique, seule insertAdjacentHTML est utilisée la plupart du temps
Modification du document

JavaScript
Suppression de noeuds
Pour supprimer un nœud, il existe une méthode node.remove().
Faisons disparaître notre message après une seconde :

<style>
.alert {
padding: 15px;
border: 1px solid #d6e9c6;
border-radius: 4px;
color: #3c763d;
background-color: #dff0d8;
}
</style>
<script>
let div = document.createElement('div');
div.className = "alert";
div.innerHTML = "<strong>Hi there!</strong> important message."
document.body.append(div);
</script>
Modification du document

JavaScript

Suppression de noeuds

Il faut noter que si nous voulons déplacer un élément vers un autre


endroit – il n’est pas nécessaire de le supprimer de l’ancien.
Toutes les méthodes d’insertion suppriment automatiquement le
nœud de l’ancien emplacement.
Par exemple, permutons les éléments :

<div id="first">First</div>
<div id="second">Second</div>
<script>
// pas besoin d'appeler remove
second.after(first);
</script>
Modification du document

JavaScript
Clonage de Noeuds : cloneNode
 elem.cloneNode(true):crée un clone “profond” de l’élément avec tous les
attributs et sous-éléments.
 elem.cloneNode(true):crée un clone sans éléments enfants.

Un exemple de copie :
<style>
.alert {
padding: 15px;
border-radius: 4px;
background-color: #dff0d8;
}
</style>
<div class="alert" id="div">
<strong>Hi there!</strong> important message.
</div>
<script>
let div1 = div.cloneNode(true);
div1.querySelector("strong").innerHTML = "Bye there!";
div.after(div1);
</script>
Modification du document

JavaScript

Méthodes d’insertion/suppression à l’ancienne

 Il existe des méthodes de modification du DOM “à l’ancienne”

 ces méthodes ne sont plus utilisé dans le JS moderne mais il faut les
connaitre pour comprendre les anciens scripts :
- parentElem.appendChild(node) : Ajoute le nœud comme dernier
enfant de parentElem.
- parentElem.insertBefore(node, nextSibling):Insère node
avant nextSibling dans parentElem.
- parentElem.replaceChild(node,oldChild):Remplace oldChild
avec node chez les enfants de parentElem.
- parentElem.removeChild(node): Supprime node de parentElem
(en supposant que node est son enfant).

Vous aimerez peut-être aussi