Live Coding : Manipuler le DOM en Javascript

Temps de lecture : 27 minutes environ.

Nous avons de nombreuses situations dans lesquelles nous devons intervenir sur la structure de nos pages ou leur contenu sans nécessité de les recgarger.

Nous allons voir ci-dessous les différentes méthodes d'accès, de modification et d'interaction avec le contenu de la page.

Toutes les techniques détaillées dans cet article se basent sur un modèle normalisé appelé DOM.

Le modèle objet du document (DOM)

Le document chargé dans le navigateur et tout son contenu est accessible au moyen du modèle objet du document (Document Objet Model en anglais), ou DOM.

C'est une structure arborescente créée par le navigateur qui permet d'accéder facilement à la structure HTML afin de manipuler la page après son chargement.

Par exemple, le code HTML ci-dessous

<!DOCTYPE html>
<html lang="fr">
<head>

</head>
<body>
<section>
<button>Cliquer ici pour ajouter du texte</button>
</section>

<section>
<div>

</div>
</section>

</body>
</html>

Donnera l'arborescence ci-dessous

Dans ce schéma, chacun des éléments et toutes les données textuelles font l'objet d'une entrée, également appelée "noeud" (node en Anglais)

Terminologie

Nous utiliserons différents termes pour décrire les différents type de noeuds et leur position dans l'arborescence par rapport à d'autres:

  • Noeud élément (element node): N'importe quel élément
  • Noeud texte (text node) : Element texte
  • Racine (root): Le noeud de plus haut niveau dans l'arbre. Dans le cas d'un document HTML, il s'agit toujours du noeud html
  • Enfant (child): Un noeud directement à l'intérieur d'un autre noeud
  • Descendant (descendent): Un noeud n'importe où à l'intérieur d'un autre noeud.
  • Parent (parent): Un noeud qui a un autre noeud directement à l'intérieur
  • Ancêtre (ancestor): Un noeud qui a un autre noeud n'importe où à l'intérieur
  • Frère (sibling): Des noeuds qui ont le même parent

Manipulations de base

Nous pourrons manipuler le document en effectuant des sélections d'éléments afin de cibler précisément le ou les noeuds sur lequel nous effectuerons des modifications.

Chargement du DOM

Il est très important d'attendre que le document soit totalement chargé avant de le manipuler.

Nous allons donc mettre en place une fonction dont le rôle est de s'exécuter automatiquement après le chargement du DOM

// On attend que le document soit chargé
window.onload = () => {
// Ici le document est chargé

}

// Ici on n'est pas certains que le document est chargé

Sélectionner des éléments

Un certain nombre d'instructions nous permettront de faire cette sélection de manière précise.

Elles fonctionnent toutes de manière similaire et renvoient dans une variable un ou plusieurs éléments correspondant à la sélection effectuée.

Il est possible, pour tous les exemples ci-dessous, de sélectionner les occurences dans l'ensemble du document en commençant par "document" ou dans les enfants d'un élément déjà sélectionné en commençant par la variable contenant cet élément.

getElementById

L'instruction getElementById permet de cibler un élément particulier de notre document en utilisant son id.

Ainsi, si notre code HTML contient ceci

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

Nous pourrons le sélectionner de cette façon

let section = document.getElementById("section1")

La variable "section" contiendra l'objet correspondant à la balise "div"

getElementsByClassName

L'instruction getElementsByClassName permet de cibler tous les éléments de notre document portant une classe précise.

Ainsi, si notre code HTML contient ceci

<div class="row"></div>
<section class="row"></section>
<footer class="row"></footer>

Nous pourrons les sélectionner de cette façon

let lignes = document.getElementsByClassName("row")

 La variable "lignes" contiendra un tableau d'objets correspondant aux 3 balises portant la classe "row".

getElementsByTagName

L'instruction getElementsByTagName permet de cibler tous les éléments de notre document portant une balise précise.

Nous pourrons les sélectionner de cette façon

let balisesDiv = document.getElementsByTagName("div")

 La variable "balisesDiv" contiendra un tableau d'objets correspondant à toutes les balises "div" de notre document.

querySelector et querySelectorAll

Depuis 2013, l'API Selectors a apporté de nouvelles façons de sélectionner des éléments dans nos documents.

Avec querySelector et querySelectorAll, nous aurons la possibilité d'effectuer des sélections en utilisant des sélecteurs CSS, beaucoup plus précis et détaillés que les simples ID, classes et balises.

La différence entre les deux méthodes est la suivante :

  • querySelector : retourne la première occurence répondant au sélecteur
  • querySelectorAll : retourne toutes les occurences répondant au sélecteur

Nous pourrons, par exemple, écrire les différentes lignes ci-dessous

// Sélectionner la première occurence qui correspond à une balise p
let baliseP = document.querySelector("p")

// Sélectionner toutes les occurences qui correspondent à une balise p
let balisesP = document.querySelectorAll("p")

// Sélectionner la première occurence qui correspond à une balise section qui a la classe "rouge"
let sectionRouge = document.querySelector("section.rouge")

// Sélectionner toutes les occurences qui correspond à un élément ayant la classe "rouge" dans une une balise section
let classeRouge = document.querySelector("section .rouge")

Lire les propriétés d'un élément

Après avoir sélectionné un élément, nous avons accès à toutes ses caractéristiques (propriétés).

Certaines propriétés, comme "style", ne sont pas prévues pour être lues. On ne pourra donc pas lire le CSS de l'élément par cette propriété (traité plus bas dans cet article)

La liste des propriétés est longue, elle est documentée sur la page MDN correspondante.

Modifier un élément

Après avoir sélectionné un élément, nous avons la possibilité de le modifier.

Les propriétés principales manipulables sont les suivantes :

  • innerHTML : le html contenu dans l'élément sélectionné
  • innerText : le texte contenu dans l'élément sélectionné (sans balises html)
  • textContent : le contenu textuel uniquement
  • style : permet de modifier le CSS de l'élément
  • value : valeur des champs de formulaire
  • attributes : les attributs de l'élément sélectionné (href, src...)

Nous pourrons par exemple modifier la couleur de fond d'un élément en écrivant ceci

element.style.backgroundColor = "blue"

Manipuler les classes

Nous pourrons aussi manipuler les classes de l'élément, en utilisant la propriété "classList" qui permet de lire, ajouter, retirer ou remplacer les classes existantes.

Les méthodes disponibles sont les suivantes :

  • add : ajoute la/les classes spécifiées en paramètre
  • remove : supprime la/les classes spécifiées en paramètre
  • item : renvoie la position de la classe spécifiée en paramètre
  • toggle : ajoute ou supprime la classe spécifiée en paramètre
  • contains : Vérifie si la classe spécifiée est présente dans l'élément
  • replace : remplace une classe par une autre

Exemple avec "toggle"

// On sélectionne la première balise "section" (par exemple)
let section = document.querySelector("section")

// On ajoute ou supprime la classe "classe"
section.classList.toggle("classe")

Lire le CSS

Il est tout à fait possible de lire le CSS actuellement appliqué à un élément. Dans ce cas, nous ne pouvons pas utiliser la propriété "style" qui n'est accessible qu'en écriture.

Il faudra, pour connaître le CSS actuellement appliqué à un élément, utiliser la méthode "getComputedStyle" couplée à la méthode "getPropertyValue".

Ces méthodes s'utilisent comme suit

// On sélectionne, par exemple, la "section"
let section = document.querySelector("section")

// On récupère la liste des styles appliqués à la section
let styles = document.getComputedStyle(section)

// On récupère la "couleur", par exemple, de la section
let couleur = styles.getPropertyValue("color")

Créer un élément

Si vous avez besoin d'ajouter du contenu dans votre page, pour insérer un nouveau commentaire par exemple, il est possible d'utiliser  la méthode "createElement".

Cette méthode va créer un élément dont nous préciserons la balise comme ceci

// Cette ligne crée une balise p
let nouvelleP = document.createElement("p")

Après avoir créé l'élément, nous pourrons lui ajouter du contenu grace à la méthode "createTextNode"

// Ces lignes ajoutent du texte dans la balise P créée juste avant
let contenu = document.createTextNode("Ceci est le contenu de la balise p")
nouvelleP.appendChild(contenu)

Enfin, nous insérerons le nouvel élément avant ou dans un élément existant.

// On sélectionne la section (par exemple)
let section = document.querySelector("section")

// On insère la balise p avant la section
document.body.insertBefore(nouvelleP, section)


// On insère la balise p dans la section, après le contenu existant
section.appendChild(nouvelleP)

Les évènements

Nous allons également pouvoir gérer les évènements qui se produitont sur notre page afin d'intéragir avec l'utilisateur.

La liste des évènements est disponible sur la page "Référence des évènements" du MDN.

Les principaux évènements qui se produiront seront générés par le clavier et la souris. Il s'agira d'évènements de clic, de saisie, mais également de survol, de focus (l'élément a le curseur), par exemple.

Pour gérer un évènement, nous allons demander au javascript d'attendre qu'il se produise, au moyen d'un "écouteur d'évènement" dont le rôle sera d'exécuter des instructions uniquement si l'évènement se produit.

La méthode permettant d'ajouter un écouteur d'évènements est "addEventListener". Il s'utilise comme ceci :

// On sélectionne la 1ère section, par exemple
let section = document.querySelector("section")

// On ajoute un écouteur d'évènements qui surveillera le clic et exécutera la fonction "fonction" quand il se produira
section.addEventListener("click", fonction)

function fonction(){
// Ce code s'exécutera lors d'un clic sur la section
}

Obtenir de l'aide

Pour obtenir de l'aide, vous pouvez accéder au serveur Discord pour une entraide par chat

Live Coding : Manipuler le DOM en Javascript
Article publié le - Modifié le

Catégories : HTML Javascript Live-Coding

Mots-clés : Javascript html html5 ES6 dom livecoding

Partager : Partager sur Facebook Partager sur Twitter Partager sur LinkedIn