---
marp: true
theme: catppuccin
paginate: true
size: 4:3
transition: coverflow
footer: ''
math: katex
lang: "fr"
---

<style>
section {
  font-size: 28px;
  text-align: left
}
</style>

# JavaScript et le DOM

---

## C'est quoi le DOM ?
(Non ce n'est pas le diminutif de Dominique)

---

- Le DOM est une API.
  - DOM = Document Object Model
    - Décrit la structure d'un document (HTML)
  - API = Application Programming Interface
    - Ensemble de fonctions utilisables dans un programme pour interagir avec un autre programme

---

Le document est composé d'éléments (noeuds) qui peuvent eux-mêmes contenir des éléments.

```html
<!doctype html>
<html lang="en">
 <head>
   <title>My first web page</title>
  </head>
 <body>
    <h1>Hello, world!</h1>
    <p>How are you?</p>
  </body>
</html>
```

![dom bg right height:80%](images/dom.png)

---

## Interagir avec le DOM

---

- Objet `document` ([doc](https://developer.mozilla.org/fr/docs/Web/API/Document)) :
  - **Propriétés** : les éléments du document
    - `body`, `head`, `doctype`...
  - **Méthodes** : pour interagir avec le document
    - Créer, supprimer ou modifier des **éléments**
    - Gérer des **évènements**
    - Manipuler le **stockage**
  - **Événements** : pour interpréter les actions des utilisateurs

---

### Sélectionner des éléments

- `document.getElementById("id")`
  - Récupère l'élément par son id
- `document.getElementsByClassName("classe")`
  - Récupère **une liste** d'éléments par leur classe
  - attention : getElement**s**
- `document.querySelector("selecteur_css")`
  - Récupère **premier** élément par le sélecteur CSS
  - ex: `#id` `.class` `balise[attribut]`...

---
<style scoped>
pre {
  font-size: 28px;
}
</style>

```html
<h3 id="titre">Bonjour !</h3>
<p class="special">Texte mis en valeur</p>
<p>Ordinaire</p>
<button id="btn">Cliquez</button>
```

```js
const title = document.getElementById("titre")
const special = document.getElementsByClassName("special")
const paragraphs = document.querySelector("p")
```

---

### Manipuler le contenu d'un élément

On manipule les propriétés d'un élément :
- `textContent` : texte de l'élément
- `innerHTML` : HTML de l'élément
- (<del>`innerText`</del> : texte de l'élément)
  - visible uniquement, pas efficace, source d'erreurs

- Les **propriétés** sont comme des **variables** : on peut les lire ou les modifier

```html
<p id="demo">Contenu initial</p>

<script>
    document.getElementById("demo").innerHTML = "<em>Nouveau contenu <strong>HTML</strong></em>";
    // Ou si on veut uniquement le texte :
    document.getElementById("demo").textContent = "Nouveau texte";
</script>
```

---

### Manipuler le style d'un élément

On manipule la propriété `style` d'un élément, qui nous donne accès aux propriétés de style (comme le CSS)

```js
titre.style.color = "red";
titre.style.fontStyle = "italic"; // Remarquez le passage au camelCase de font-style
```

**Remarque** : la casse des propriétés de style
- en JS : `camelCase` 
- en CSS :  `kebab-case`

---

### Créer, insérer, remplacer, supprimer des éléments

- Créer : `createElement("balise");`
- Insérer : 
  - `appendChild(nouvel_element)` : ajoute un enfant à un élément parent
  - `insertBefore(nouvel_element, autre_element)` : ajoute un élément avant un autre
- Remplacer :
  - `replaceChild(nouvel_element, ancien_element)`
- Supprimer :
  - `remove()` : supprime l'élément sur lequel elle est appliquée
  - `removeChild(element)` : retire l'élément enfant d'un élément parent

---
```html
<div id="container">
  <p id="parag1">Paragraphe 1</p>
  <p id="parag2">Paragraphe 2</p>
</div>
```

```js
const container = document.getElementById("container");

// CRÉER un nouvel élément <p>
const nouveau = document.createElement("p");
nouveau.textContent = "Nouveau paragraphe créé";

// INSÉRER à la fin du container
container.appendChild(nouveau);

// REMPLACER le paragraphe 1 par un nouveau
const remplacement = document.createElement("p");
remplacement.textContent = "Je remplace le premier paragraphe";
const parag1 = document.getElementById("parag1");
container.replaceChild(remplacement, parag1);

// SUPPRIMER le paragraphe 2
const parag2 = document.getElementById("parag2");
parag2.remove();
```
---

### Gérer les évènements

**Évènements** : actions qui se produisent dans le navigateur
- Clic de souris
- Frappe au clavier
- Chargement de page

- On gère les interactions grâce aux évènements
  - On lie un évènement à un gestionnaire d'évènement
  - **Gestionnaire d'évènement** : fonction appelée quand l'évènement survient

---

#### Attributs

On peut lier un gestionnaire d'évènement à un évènement grâce à un attribut dans le HTML

```html
<button id="btn" onclick="alert('Bouton cliqué !')">Cliquez-moi</button>
```
- `onclick` : appelle le code quand on clique sur le bouton 
- Facile et rapide mais **mauvaise pratique**
  - Mélange HTML et JavaScript
    - mauvaise séparation des responsabilités
  - Peu flexible
    - un seul gestionnaire à la fois
    - difficile à maintenir

---

#### EventListener

On préfère cette méthode : lier un gestionnaire d'évènements à un évènement dans le code JS
- méthode `addEventListener`

```html
<button id="btn">Cliquez-moi</button>
```

```js
const bouton = document.getElementById("btn");
bouton.addEventListener("click", function() {
    texte.textContent = "Bouton cliqué !";
  });
```

---

Plusieurs types d'évènements :
- `input` : modification d’une zone de saisie
- `change` : changement d’état (ex. : sélection)
- `mouseover` / `mouseout` : passage de la souris sur un élément
- `keydown` / `keyup` : touches du clavier pressées ou relâchées.
​