Manipulation du DOM

Technologie web 2

Johan Girod

Rappel sur les éléments HTML

Document HTML

Exemple



	
  • Un document HTML est composé d'éléments imbriqués les uns dans les autres
  • Ces éléments sont délimités par des balises ouvrantes et fermantes.
  • Les éléments racines sont <html>, <head> et <body>

Que trouve-t-on dans l'élément <head> ?

Des métadonnées (tout ce qui n'est pas visible sur la page)
  • Le titre de la page <title>
  • Les feuilles de style <link rel="stylesheet" href="style.css">
  • La description <meta name="description" content="...">
  • L'encodage du document <meta charset="utf-8">
  • Et bien d'autres (favicon, scripts, données pour les réseaux sociaux, etc.)

Anatomie d'un élément

<a class="ma-class" href="/" > Revenir à l'accueil </a>
Type de l'élément ⋅ Attributs ⋅ Contenu

Anatomie d'un élément

Un élément peut contenir d'autres éléments



				

Qu'est-ce que le DOM ?

Qu'est-ce que le DOM ?

Le DOM (Document Object Model) est une interface de programmation pour manipuler des documents HTML en Javascript
  • Tous les navigateurs implémentent le DOM (standard web)
  • Les scripts JavaScript l'utilisent pour lire et modifier le HTLM affiché à l'écran

Le document est représenté sous forme d'arbre



Le document est représenté sous forme d'arbre

DOM tree

Le DOM est implémentée par les navigateurs

Rendering pipeline : parsing, render tree, layout, paint

C'est l'étape de parsing (ou analyse syntaxique)

Accéder au DOM en JavaScript

Le DOM est accessible via l'objet global document


			

Cet objet contient des propriétés et des méthodes pour manipuler le document


			
	

L'API du DOM

Récupérer un élément (noeud de l'arbre)

document.querySelector("...")



			>

Renvoie le premier élément correspondant au sélecteur CSS.
Retourne null si aucun élément n'est trouvé.

Lire le contenu

Code HTML


		
		

Code JavaScript

			
				
			
		

Modifier le contenu

Code HTML


		
		

Code JavaScript

			
				
			
		

Lire et modifier les classes CSS

Code HTML


				
					

Code JavaScript


						
						

		
	

Lire et modifier le style CSS

Code JavaScript


	const color = element.style.color;

	element.style.fontSize = '2rem';
		

Lire et modifier des attributs

Code JavaScript


	/* Lire et modifier les attributs : méthode générique */
	const placeholder = element.getAttribute('placeholder');
	element.setAttribute('src', 'image.jpg');

	/* Lire et modifier les attributs : accesseur direct
	 (dans certains cas seulement) */
	const valeur = input.value;
	a.href = 'https://google.com';
	

Ajouter des nouveaux noeuds dans le DOM

1. Créer un noeud


			
		

2. Insérer un noeud


			
	

Attention ! Un noeud doit être inséré pour être visible sur la page. Sinon, il n'existe que dans la mémoire de l'ordinateur.

Supprimer, cloner, remplacer un élément


			
	

Se déplacer dans le DOM

Le DOM est un arbre, on peut se déplacer d'un noeud à l'autre avec les propriétés suivantes :


		
	

Récupérer une liste d'élément

document.querySelectorAll("...")



			>

Renvoie une collection (NodeList) de tous les éléments correspondant au sélecteur CSS.


			
	

NodeList : pas tout à fait un tableau

L'objet retourné par querySelectorAll n'est pas un tableau JavaScript classique.

Pour utiliser les méthodes de tableau (filter, find etc.), il faut d'abord le convertir en tableau :


			
	

À vous de jouer !

johangirod.com/cours

Exercices / TP

Mise en place

Ce TP est disponible sur gitlab. Vous pouvez le cloner avec la commande suivante :

git clone https://sources.univ-jfc.fr/techno-web-2/tp-2.git

Utilisez les identifiants de votre compte universitaire pour vous connecter.

Utilisation de Gitlab pour sauvegarder votre travail (facultatif)

Pour sauvegarder votre travail sur votre compte Gitlab, vous devez d’abord créer une bifurcation (fork) du repo.

Cliquez ici pour créer une bifurcation.

Une fois le repo créée, vous pourrez le cloner en utilisant l’URL fournie par Gitlab (bouton bleu « Code »).

Ouvrez le dossier tp-2 dans votre éditeur de code (VSCode par exemple).

Ce projet contient un fichier index.html.

Ouvrez le fichier index.html dans votre navigateur (double-cliquez sur le fichier) pour voir le résultat de votre travail.

Exercice 1 : modifier un élément avec la console

Pour commencer, nous allons nous familiariser avec la modification du DOM en utilisant la console du navigateur.

  • Faire un clique droit sur la page et sélectionner « Inspecter » dans le menu contextuel. Cela ouvre l’inspecteur du navigateur et affiche le code HTML correspondant.

  • Cliquez sur l’onglet console et tapez la commande suivante :

    $0;

    Que contient la variable $0 ? Cliquez sur un autre élément dans l’inspecteur et de taper la commande $0 à nouveau. Que remarquez-vous ?

    Corrigé
  1. Faire en sorte que $0 pointe vers le noeud DOM <p> qui contient le texte « Bonjour tout le monde ! ». Vous pouvez vous aider du bouton « selection » en haut à gauche de l’inspecteur (sous forme de pointeur de souris). Il vous permet de selectionner un élement directement depuis la page web.

  2. Dans la console, tapez la commande suivante pour changer le texte de l’élément sélectionné :

    $0.textContent = 'Bonjour les amis !';
  3. Changez la couleur du texte en rouge en utilisant la propriété style de l’élément (comme vu dans le cours).

  4. Supprimer le noeud de la page en utilisant la méthode remove().

Exercice 2 : modifier un élément avec du code JavaScript

Nous allons réaliser une diapositive d’images qui changent toutes les 2 secondes.

  1. Pour commencer, créer un fichier script.js, et faire en sorte qu’il soit exécuté au chargement de la page. Pour cela, il faudra ajouter un lien grâce à la balise <script> dans le <head> du fichier index.html.

    <script defer src="./script.js"></script>
    L'attribut `defer`

    defer est un attribut booléen qui indique au navigateur de différer l’exécution du script après le chargement de la page. Cela permet de garantir

    • que le script ne bloque pas le rendu de la page
    • que les éléments du DOM sont bien chargés avant l’exécution du script

    Sans cet attribut, le script est exécuté au moment où il est rencontré dans le fichier HTML, ce qui peut poser des problèmes si le script est placé dans le <head>.

    Pourquoi ?

    Corrigé

  2. Dans le fichier script.js, récuperez le l’élément DOM existant de l’image dans une variable imageNode. Le noeud HTML est une image img avec pour id diapo.

  3. Créez une fonction changeImage() qui change l’attribut src de l’image pour pointer vers image aléatoire.

    Dans la fonction, générez un id aléatoire entre 1 et 500 et utilisez cet id pour construire l’url de l’image. Par exemple, si l’id aléatoire est 3, l’url vers la nouvelle image sera https://picsum.photos/id/3/400/400.

    Faire en sorte que la fonction change l’attribut src de l’image pour pointer vers cette nouvelle url.

  4. Appelez la fonction changeImage() toutes les 2 secondes en utilisant la fonction setInterval.

    // setInterval va appeler la fonction changeImage toutes les 2 secondes
    setInterval(changeImage, 2000);
Corrigé

Exercice 3 : Modifier le style d’éléments avec du code JavaScript

Écrire un script qui cache tous les éléments avec la class hidden par un rectangle noir (on pourra utiliser l’attribut style pour changer la couleur de fond en noir).

Corrigé

Exercice 4 : Un jeu de mémoire en JavaScript

Nous allons développer un petit jeu de mémoire.

Le but est de faire apparaitre 5 cartes contenant des emojis aléatoires pendant 10 secondes. Ensuite, les emojis disparaissent et on pose la question à l’utilisateur : « Sous quelle carte se trouve l’emoji X ? ».

1. Selections des emojis

Créez la fonction getRandomEmojis() qui retourne un tableau de 5 emojis aléatoires différentes. Voici son code (à compléter)

// prettier-ignore
const emojis = [ '⛔️', '❇️', '🏰', '🐺', '⚜', '😅', '🚳', '🕞', '❣', '🏬', '🛎', '🌕', '🌃', '🏡', '🎑', '🍯', '🐍', '🔕', '🐿', '💮', '😹', '↕️', '🌵', '♒️', '🚽', '🕋', '📔', '🛂', '🎒', '🐼', '♏️', '⏸', '🅰️', '🌈', '🌂', '🚣', '🎇', '❄️', '👙', '🌹', '🍸', '🛳', '🎟', '😱',  '👳', '😑', '⌚️', '💛', '🆚', '🔼', '🈯️', '☀️', '😳', '♊️', '🌖', '♋️', '🚀', '🚱', '🚊', '📿', '⏫', '9️⃣', '🗾', '🏜', '🍦', '✋', '🍀', '🗿', '🙎', '✖️', '🆕', '🎮', '🔒', '💸', '👲', '🏢', '🔑', '🐶', '👪', '😻', '🌼', '👠', '🧀', '👎', '🙌', '🐻',  '👯',  '😺', '😈', '💴', '🎾', '🚙', '❤️', '♑️', '🌲'];
function getRandomEmojis() {
	const randomEmojis = [];
	while (randomEmojis.length < 5) {
		// 1. On selectionne un index aléatoire entre 0 et la longueur du tableau emojis
		const randomIndex = ?
		// 2. On récupère l'emoji correspondant à cet index
		const randomEmoji = ?
		// 3. On vérifie si l'emoji n'est pas déjà dans le tableau (utiliser includes)
		const isAlreadyInArray = ?
		if (!isAlreadyInArray) {
		  // 4. Si l'emoji n'est pas déjà dans le tableau, on l'ajoute
		}
	}
	// On retourne le tableau
	return randomEmojis;
}
Corrigé

2. Affichage des emojis

Creer une fonction displayCards(emojis) qui prend en paramètre un tableau d’emojis à afficher. Cette fonction va créer des éléments HTML <li> pour chacune des emojis et les insérer dans le DOM.

function displayCards(emojis) {
  // 1. Selectionner l'élement du DOM `<ol id="emoji-game"> dans la variable emojisContainer
	const emojisContainer = ?
	// 2. Supprimer son contenu (réinitialise la liste)
	emojisContainer.innerHTML = '';
	// 3. Pour chacune des emoji du tableau
	for (const emoji of emojis) {
	  // a. Créer un nouvel element HTML de type `li` (element de liste)
		const emojiNode = ?
		// b. Remplir son contenu par l'emoji courante
		?
		// c. Ajouter l'élément comme enfant de l'élément emojiContainer (à l'intérieur)
		?
	}
}

Testez cette fonction en appelant displayCards(getRandomEmojis()). Vous devriez voir les emojis s’afficher dans le navigateur.

Corrigé

3. Cacher les emojis

Créer une fonction hideEmojis qui cache le contenu en modifiant la couleur de chacune des cartes à transparent. emojiCard of emojiCards Pour sélectionner toutes les éléments contenant des emojis, on pourra utiliser la méthode querySelectorAll avec le sélecteur CSS approprié.

Testez cette fonction avec le code suivant

displayCards(getRandomEmojis());
setTimeout(hideEmojis, 2000); // Appel la fonction hideEmojis après 2 secondes
Corrigé

4. Poser une question à l’utilisateur

Créer une fonction askQuestion avec les spécifications suivantes : , et pose la question à l’utilisateur : « Quelle est le numéro de la carte avec l’emoji ? » (avec l’emoji choisie).

/**
 * @param {string[]} randomEmojis - Tableau d'emojis aléatoires affiché à l'utilisateur.
 */
function askQuestion(randomEmojis) {
	// 1. On choisi un emoji aléatoirement dans ce tableau
	// 2. On pose la question à l'utilisateur : « sous quel carte se trouve l'emoji <emoji> ? »
	// 3. Si l'utilisateur répond correctement, alors :
	//    a. On ajoute la classe `success` à l'élement <ol id="emoji-game">
	//    b. On affiche le text "Bravo 🎉 !" dans l'élément <div id="emoji-game-message">
	// 4. Sinon :
	//    a. On réaffiche toutes les emojis
	//    b. On affiche le texte 'Perdu 😔' dans l'élément <div id="emoji-game-message">
}

Testez que la fonction askQuestion fonctionne en l’appelant avec un tableau d’emojis (vous pouvez afficher la solution dans le texte de la question pour tester le cas où l’utilisateur répond correctement).

Corrigé

5. Assemblage du jeu

  1. Créer une fonction startGame qui appelle successivement les fonctions getRandomEmojis et displayCards.

  2. Utilisez la fonction setTimeout pour appeler la fonction hideEmojis après 5 secondes.

    setTimeout(hideEmojis, 5000);
  3. Utilisez la fonction setTimeout pour appeler la fonction askQuestion après 5 secondes et 100 millisecondes.

  4. Appelez la fonction startGame pour lancer le jeu.

Corrigé

6. Pour aller plus loin

  1. Faire en sorte que le jeu boucle tant que l’utilisateur ne trouve pas la bonne réponse, en affichant les emojis pendant 5 secondes puis en posant une nouvelle question.

  2. Faire en sorte que le jeu augmente en difficulté à chaque fois que l’utilisateur trouve la bonne réponse, en ajoutant un emoji supplémentaire à chaque tour. Afficher un compteur de niveau. Si l’utilisateur se trompe, le niveau est réinitialisé à 1.