Valentin Dupas

💡 If this is the first course you read from me, please read this small thing : about my courses

Un avant goût

Dans la version précédente du cours j'avais tout expliqué dans le detail d'abord, puis montré comment se servir de javascript pour rendre une page interactive. Sans grand succès. Dans cette itération je vais d'abord vous fournir une vue d'ensemble en montrant comment construire ce petit projet. Puis dans le chapitre suivant on verra les détails de ce que nous avons utilisé dans ce chapitre.

Mise en place

Créez un nouveau projet, ouvrez le dans VSCode et collez le code ci-dessous dans un fichier index.html.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Incrementer example</title>
    <style>
      body {
        min-height: 100vh;
        margin: 0;

        font-family: system-ui, sans-serif;

        display: grid;
        place-items: center;

        font-size: 32px;
      }

      main {
        display: flex;
        align-items: center;
        gap: 3rem;
      }

      button {
        font-size: 1rem;
        padding: 1rem;
      }
    </style>
  </head>
  <body>
    <main>
      <div id="count"></div>
      <button>+</button>
    </main>

    <script>
      // rappel: le javascript c'est ici
    </script>
  </body>
</html>

Cool, à partir de là on ne s'intéressera plus qu'au javascript.

Mettre la main sur un truc

En CSS il vous faut selectionner des éléments pour pouvoir leur appliquer des règles, eh bien on va se reservir de ces même sélecteurs. La fonction document.querySelector() nous permet de sélectionner le premier élément qui correspond au selecteur CSS qu'on lui fournit.

Autrement dit, je peux dire à mon programme de sélectionner le boutton comme ceci

document.querySelector("button");

Si vous cherchez à executer ce bout de code, il n'y aura rien à voir. Mais je vous ai dit que console.log était extrêmement utile, on peut s'en servir pour afficher autre chose que du texte. Essayons de s'afficher notre bouton.

console.log(document.querySelector("button"));

Avec cette ligne vous devriez voir votre bouton, que vous pouvez ouvrir et inspecter pour voir toutes les informations que le navigateur a desssus.

button in the console log

La vieille méthode

J'écris ça en 2024 et pourtant, pas mal de gens/tutos risquent encore de vous parler de document.getElementById(). Je vous encourage a toujours utiliser document.querySelector() parce que vous pouvez utiliser n'importe quel selecteur CSS plutôt que juste un id et pas autre chose.

Aussi, c'est beaucoup plus lisible d'un coup d'œil. Si je vois un # entre les paranthèses de document.querySelector() alors je sais que je fais de la sélection par identifiant, si je vois un . entre ses paranthèses alors je fais de la sélection par classe, si ça ne commence par aucun charactère spécial alors c'est de la sélection par tag etc...

Cela dit, peut être que document.getElementById() est plus rapide à faire pour la machine et aurais donc sa place, mais bon ... ce genre de considérations ne nous regarderont pas dans ce cours et ne regardent probablement pas non plus ceux qui vous le conseilleront.

Lire les infos d'un truc

On peut spécifier une propriété particulière avec un .. Par exemple ...

document.querySelector("button").textContent;

J'attrape mon bouton avec document.querySelector("button") puis dedans je récupère le texte qu'il contient, le tout en une seule ligne ce qui fait que le résultat du total est "le contenu textuel de mon bouton".

Et on peut verifier ça en se l'affichant :

console.log(document.querySelector("button").textContent);

button content

Modifier un truc

Je peux aussi sélectionner une propriétes et lui donner une nouvelle valeur comme ceci

document.querySelector("button").textContent = "c'est mon bouton";

Ce coup-ci, pas besoin de console.log() pour voir les effets de notre manip'.

Le bouton labelisé "c'est mon bouton"

Il faut savoir que = ici veux dire que l'on rend la chose à gauche égale à celle de droite, donc cette ligne équivaux à "le textContent du premier élément <button> que l'on trouve dans le document devient égal à "c'est mon bouton"".

Exercice

En modifiant uniquement le javascript de votre projet, changez le texte de l'élément ayant l'identifiant count. Donnez lui la valeur que vous voulez.

Rappel: Le sélécteur CSS pour les id est #. Par exemple: #myId. De la même manière que le sélécteur pour une classe est . comme dans .myClass.

Solution
document.querySelector("#count").textContent = 42;

ça marche aussi

document.querySelector("#count").textContent = "42";

Ce n'est pas très important tout de suite mais la différence est que dans le premier cas on lui donne le nombre 42 tandis que dans le deuxième cas on lui donne le texte "42".

Passer de l'action à l'intéraction

On peut demander à un élément particulier de réagir à certains types d'événements. Quand on lui demande ça il faut lui dire à quel type d'événement réagir et quoi faire.

Si je reprend mon bouton...

document.querySelector("button");

... il faut que j'aille chercher dans ce qu'il possède avec . pour donner la commande "met toi à l'écoute d'un type d'événement".

document.querySelector("button").addEventListener(/*l'événement et quoi faire*/);

Si on écrit ceci ...

document.querySelector("button").addEventListener("click", handleClick);

... on demande à notre bouton d'éxécuter l'action handleClick lorsequ'il est cliqué. Remarquez que "click" est encadré par des guillemets " alors que handleClick ne l'est pas. Ce qui est encadré dans des guillemets est purement du texte, le reste est du code, handleClick est le nom d'une action/fonction qui n'existe pas encore, c'est à nous de la créer comme ceci.

document.querySelector("button").addEventListener("click", handleClick);

function handleClick() {
  console.log("clique");
}

Ici "click" est du texte parce que addEventListener() est prévue comme ça, elle connais une liste d'événements, chaque événement correspondant à un texte, pour le moment on va se contenter de "click".

Et si on clique 7 fois sur notre bouton voici ce que l'on a dans la console.

"clique" affaiche 7 fois dans la console

On y est presque, on peut essayer de remettre ensemble tout ce qu'on viens de voir

document.querySelector("button").addEventListener("click", handleClick);

function handleClick() {
  document.querySelector("#count").textContent = 1;
}

Bon, c'est marrant, mais on vois bien qu'il nous manque un truc parce qu'on reste coincé sur 1, ce qui est normal vu que handleClick assigne la valeur 1 au textContent de l'élément #count à chaque fois et c'est tout.

En sachant qu'on exécute le code contenu dans la fonction handleClick à chaque fois que l'on clique sur le bouton. Ce serait bien si on pouvait garder en mémoire le nombre auquel on est rendu.

Et c'est ce qu'on va faire, on peut définir un nom auquel on peut associer une valeur comme ceci

let countNumber = 0;

let est un mot-clef signifiant que l'on créer une "variable" qui est juste un nom associé à une valeur. Ici on créer le nom countNumber et on lui associe la valeur 0. Une fois que ce nom existe on peut lui donner une nouvelle valeur avec =, comme ceci:

let countNumber = 0;

console.log("countNumber");
console.log(countNumber);

countNumber = 42;

console.log(countNumber);

Nous donnant ceci dans la console

"countNumber", 0 et 42 affichés dans la console

Pour continuer d'illustrer la différence entre du texte brut et du code vous remarquerez que dans le premier console.log() j'ai encadré countNumber par des guillemets et c'est donc exactement ce que j'ai d'affiché. En revanche, quand je met countNumber directement on parle bien la valeur countNumber qui est d'abord 0 puis 42.


La vieille méthode

Pareil, toujours en 2024, il y aura des gens pour vous montrer var au lieux de let. Ça pour le coup ce n'est pas justifiable.

let à été introduit dans le langage en 2016 pour remplacer var qui ouvrait la porte à trop de bugs et comportements foireux.


Et donc je peux tout remmetre ensemble comme ceci

document.querySelector("button").addEventListener("click", handleClick);

function handleClick() {
  let count = 0;
  count = count + 1;
  document.querySelector("#count").textContent = count;
}

Essayez ce code ci-dessus.

Qu'est-ce que ça donne?

Ça donne la même chose parce qu'à chaque fois qu'on exécute le code contenu dans handleClick on ...

  1. créer count qui vaux 0
  2. puis on l'augmente de 1 en disant qu'il est maintenant égal à lui même + 1
  3. on dit que la valeur du texte de #count devient égale à la valeur de count

Mais il faut savoir qu'une variable, comme count, n'existe que dans le "scope" (qu'on pourrait vaguement traduire par "environement") dans lequel elle a été créée, et sera détruite une fois que tout le code du scope aura été exécuté. Un scope est delimité par les accolades {} qui nous encadrent le plus directement. Donc count est créé dans le scope de handleClick. Ce qui veux dire qu'à chaque fois qu'on fini d'exécuter le code de handleClick on détruit count que l'on recréera en partant du nombre 0 la prochaine fois que l'on exécutera handleClick. Donc il faut sortir count du scope de handleClick pour qu'elle surive et garde sa mémoire entre deux exécutions de handleClick.

let count = 0;

document.querySelector("button").addEventListener("click", handleClick);

function handleClick() {
  count = count + 1;
  document.querySelector("#count").textContent = count;
}

Et voila 🎉

Probleme : Faites un bouton - qui fait redescendre le compteur de 1 quand on clique dessus.

Indice

Rappellez vous du tout début de ce chapitre, document.querySelector() ne selectionne que le premier élément qui correspond. Maintenant nous avons 2 boutons, il faut donc un moyen de les différencier, pour ça on peut leur coller des identifiants.

Solution

html

<!-- [...] -->
<main>
  <button id="minus-button">-</button>
  <div id="count">0</div>
  <button id="plus-button">+</button>
</main>
<!-- [...] -->

js

<script>
  let count = 0;

  document.querySelector("#minus-button").addEventListener("click", countDown);
  document.querySelector("#plus-button").addEventListener("click", handleClick);

  // ici je conserve `handleClick` pour changer le moins de choses possible
  // mais je déteste ce nom parce qu'il explique mal ce qu'il fait
  // `countUp` serait largement mieux.
  function handleClick() {
    count = count + 1;
    document.querySelector("#count").textContent = count;
  }

  function countDown() {
    count = count - 1;
    document.querySelector("#count").textContent = count;
  }
</script>