LIFWEB TP2-a - Manipulation du DOM

On donne les fichiers de départs suivants :

Quand on indique dynamiquement, on entend en JS en manipulant le DOM, pas en éditant les sources des HTML ou CSS.

Il est recommandé d’utiliser l’extension https://ritwickdey.github.io/vscode-live-server/ (VSCode, Open-VSX) et de choisir qu’elle ouvre la page dans un navigateur en navigation privée (option liveServer.settings.CustomBrowser).

Exercice 0 (PRÉPARATION) : Chargement de JS

  • Identifier sont chargés les différents scripts JavaScript.
  • Expliquer l’ordre des affichages dans la console.
  • Conclure sur les longueurs des NodeList affichées.
  • Avec console.log() afficher le nombre de <li> de la page.

Exercice 1 : DOM et Événements

  • Ajouter dynamiquement à document.body un bouton avec le texte RàZ.
    • Faire en sorte que le bouton RàZ soit positionné à droite du bouton Démo.
    • Utiliser par exemple Element.insertAdjacentElement() (MDN).
  • Ajouter un handler au bouton Démo pour qu’il ajoute une nouvelle ligne de texte dans l’élément code (id=output-code) avec le nombre de fois où on a cliqué sur le bouton Démo.
    • Pour ce TP, on se satisfera pour l’instant d’une variable compteur globale.
  • Ajouter un handler au bouton RàZ qui aura pour effet de vider l’élément code et de remettre à zéro le compteur précédent.
  • Faire en sorte que quand on clique sur le bouton Calculer, un pop-up s’affiche avec le carré du nombre saisi dans le champ <input id="input-int">.

Pour le retour à la ligne, on peut commencer par utiliser .innerHTML et dans un second temps, utiliser .textContent, Document.createTextNode (MDN) et un élément <br>.

Exercice 2 : Toggling de classe CSS

  • Ajouter statiquement un nouvel élément <style> à l’en-tête HTML qui définit une classe CSS qui met la couleur de fond en rouge.
  • Ajouter dynamiquement un handler sur le bouton Exercice 2 pour que chaque clic alterne la couleur du bouton avec la classe précédente :
  • Faire en sorte qu’au 10ème clic le bouton devienne désactivé (attribut disabled).
  • Remplacer l’élément statique <style> par un ajout dynamique en JS.

Exercice 3 : Affichage d’images

L’élément <ul id="images-list"> contient des liens utilisés sur le site https://www.sudtourisme.nc/.

  • Modifier la page pour qu’à chaque clic sur un lien, l’image correspondante est affichée dans l’élément <div id="image-container">.
  • Définir des classes CSS pour contrôler l’affichage de l’image afin qu’elle soit de taille 80% de la largeur d’affichage et centrée dans le <div>.
    • Utiliser les Flexbox pour le positionnement
    • Cela peut se faire en statique via la CSS (en donnant si besoin les classes via JS)

Exercice 4 : Konami Code

Le Konami Code est la séquence de touches haut, haut, bas, bas, gauche, droite, gauche, droite, B, A. Ajouter un easter egg à la page : si l’utilisateur saisi le Konami Code, un message alert() se déclenche. Pour cela, il faudra :

  • Écouter l’événement document.onkeydown.
  • Accéder à l’attribut key (MDN) de l’événement passé en paramètre du handler de onkeydown.
  • Maintenir un compteur avec le nombre de frappes valides de la séquence, et le remettre à zéro si la touche appuyée n’est pas la bonne.

On donne ci-dessous la séquence JS avec le code des touches.

const konamiCode = [
  "arrowup",
  "arrowup",
  "arrowdown",
  "arrowdown",
  "arrowleft",
  "arrowright",
  "arrowleft",
  "arrowright",
  "b",
  "a",
];

Exercice 5 (BONUS) : suivi de souris

On donne la définition de la classe dot suivante qui permet d’afficher un gros point. On va utiliser cette classe pour traquer le curseur de la souris avec ce point.

.dot {
  pointer-events: none;
  height: 50px;
  width: 50px;
  background-color: #bbb;
  border-radius: 50%;
  display: inline-block;
  position: absolute;
}
  • Ajoutez dynamiquement (en JavaScript) ou statiquement (dans le HTML) un div avec la classe dot.
  • Créez une fonction followMouse() qui aura le comportement suivant.
    • Elle garde une variable locale mousePos qui va stocker la position courante de la souris.
    • Elle associe à l’événement mousemove un handler qui met à jour mousePos.
    • Elle déclenche toutes les 50ms avec setInterval(handler, delay) (MDN) une fonction qui lit mousePos et positionne le point sous le curseur en modifiant les attributs CSS left et top du div.

Utiliser le bouton Follow mouse, pour que lors d’un clic :

  • Si le traqueur n’est pas actif, on l’active,
  • Si le traqueur est déjà actif, on le désactive :
    • on cache le cercle avec circle.style.display = "none"; ;
    • on supprime le handler de mousemove ;
    • on arrête le timer de setInterval.

Notons que là aussi, on se satisfera de variables globales pour ce TP.

Plutôt que d’utiliser setInterval(handler, delay), on pourra faire une version avec requestAnimationFrame() qui produira une animation beaucoup plus fluide.

Exercice 6 : tableau triable

On donne un tableau HTML comme suit à insérer dans votre page :

<table id="the-table">
  <thead>
    <tr>
      <th data-type="number">Age</th>
      <th data-type="string">Name</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1</td>
      <td>Romuald</td>
    </tr>
    <tr>
      <td>2</td>
      <td>Edouard</td>
    </tr>
    <tr>
      <td>12</td>
      <td>Matthieu</td>
    </tr>
    <tr>
      <td>9</td>
      <td>Jerry</td>
    </tr>
    <tr>
      <td>10</td>
      <td>Winston</td>
    </tr>
  </tbody>
</table>

On note qu’on utilise les éléments <thead>, <th> ainsi que des attributs HTML data-* qui permettent de personnaliser les éléments (MDN). On peut accéder à ces attributs avec la propriété HTMLElement.dataset (MDN), par exemple avec le header du tableau :

document.querySelector("#the-table th").dataset.type;

Ajouter une fonctionnalité qui permet de trier les lignes du tableau quand clique sur le nom de la colonne. On utilisera :

  • Une délégation d’événements sur <thead>
  • L’attribut data-type pour utiliser le bon type lors du tri des lignes, avec String.localeCompare() pour les chaînes (MDN).
  • L’attribut cellIndex pour connaître le numéro de colonne (MDN).

Le travail consiste essentiellement à écrire la bonne fonction de comparaison pour la méthode Array.sort() sur les lignes <tr> du tableau, Array.sort() par défaut ne fait pas vraiment ce qu’on attend.

Ensuite, ajouter un état aux colonnes pour qu’on puisse trier dans l’ordre croissant au premier clic, puis décroissant au second, etc.

Enfin, rajouter une colonne de type date (MDN) triable elle aussi. On fera vérifiera que la date 2023-12-01 14:20 est bien après 2023-12-1 11:23 (c’est l’inverse dans l’ordre lexicographique).

Exercice 7 (BONUS) : l’API Intl

L’API Intl (MDN) est un objet qui propose des méthodes statiques (dites aussi de classe) pour gérer les calendriers, l’ordre des caractères (collation), les devises, les systèmes de numérotation les fuseaux horaires et les unités dans les différentes langues. On donne deux <select> (MDN) pour choisir une langue et un fuseau horaire comme ci-dessous.

<select id="select-lang">
  <option value="fr">Français</option>
  <option value="en">Anglais</option>
  <option value="de">Allemand</option>
  <option value="es">Espagnol</option>
</select>

<select id="select-timezone">
  <option value="Europe/Paris">Paris</option>
  <option value="Europe/London">Londres</option>
  <option value="America/Guadeloupe">Guadeloupe</option>
  <option value="Pacific/Wallis">Wallis</option>
</select>

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

L’exercice consiste à afficher dans le <div> la date et l’heure courante (new Date()) au format complet, dans la langue et le fuseau sélectionnés. On lira par exemple :

  • mercredi 24 janvier 2024 à 04:15:39 heure de Wallis-et-Futuna, si on choisit Français/Wallis ;
  • Tuesday, January 23, 2024 at 12:15:39 PM Atlantic Standard Time, si on choisit Anglais/Guadeloupe ;
  • martes, 23 de enero de 2024, 16:15:39 (hora del meridiano de Greenwich), si on choisit Espagnol/Londres ;
  • etc.

On mettra à jour l’heure chaque seconde avec setInterval(handler, delay) (MDN). Pour l’affichage, on utilisera Intl.DateTimeFormat (MDN). On pourra prendre des langues dans la liste internationale et des fuseaux avec Intl.supportedValuesOf() (MDN).