# Le WEB <iframe src="https://player.vimeo.com/video/138623515?h=16b49aa8b4&color=fc535c&title=0&byline=0&portrait=0" width="640" height="360" frameborder="0" allow="autoplay; fullscreen; picture-in-picture" allowfullscreen></iframe> --- Le Web est une application du réseau Internet qui désigne un réseau de sources d'information reliées par des l**iens hypertextes**. Le Web fonctionne selon **l'architecture client/serveur** : la machine *client* demande à la machine *serveur* une ressource identifiée par son adresse [URL](https://developer.mozilla.org/fr/docs/Glossaire/URL). Aux débuts du Web le client était commandé par un humain mais ce peut être un programme. --- ## Modèle client-serveur <iframe src="https://player.vimeo.com/video/138623558?color=b50067&title=0&byline=0&portrait=0" width="640" height="360" frameborder="0" allow="autoplay; fullscreen; picture-in-picture" allowfullscreen=""></iframe> --- Dans un échange sur le Web, le __client__ envoie une demande ou __requête__ à l'aide d'un logiciel appelé __navigateur__ : le __serveur__ est un logiciel installé sur une machine reliée en réseau à la machine du client.  --- ## Les trois piliers du Web : URL, HTTP et HTML Les inventeurs du Web, [Tim Berners-Lee](https://interstices.info/les-debuts-du-web-sous-loeil-du-w3c/) et [Robert Caillau](https://fr.wikipedia.org/wiki/Robert_Cailliau) ont défini au [CERN](https://fr.wikipedia.org/wiki/Organisation_europ%C3%A9enne_pour_la_recherche_nucl%C3%A9aire) entre 1989 et 1991 ses trois piliers [HTTP](https://developer.mozilla.org/fr/docs/Glossaire/HTTP), [URL](URL) et [HTML](HTML). --- ## URL Une adresse **URL** pour `Uniform Ressource Locator` identifie une ressource sur le Web. La syntaxe des URL est standardisée, par exemple décomposons l'URL : ```url https://www.gnu.org/gnu/linux-and-gnu.fr.html ``` * le **protocole** est `https` ; * le **nom de domaine** sur Internet du **serveur Web** est `gnu.org`. `www.gnu.org` est un **sous-domaine** servant d'alias pour le d**ossier public** du serveur ; * `gnu/linux-and-gnu.fr.html` est le **chemin** vers la ressource sur le serveur : le **fichier** `linux-and-gnu.fr.html` qui se trouve dans le **dossier public** `gnu`. --- ## Protocole HTTP Acronyme d'`Hypertext Transfer Protocol`, c'est un protocole de la couche application qui décrit le format des échanges de données entre un client et un serveur sur le Web. --- Un échange HTTP s'établit selon le schéma suivant : * Le client saisit une **URL** dans la barre d'adresse du navigateur, elle est résolue en adresse **IP** par le service **DNS**. * Mise en place d'une connexion **TCP** entre le client et le serveur. * Le client envoie une requête **HTTP** (format texte lisible par un humain). * Le serveur retourne une réponse **HTTP**, lue par le client. S'il y a un contenu, il est affiché par le navigateur du client. * Fermeture ou réutilisation (paramètre `Keep-alive`) de la connexion pour les requêtes suivantes. ---  --- ## Récapitulatif <iframe src="https://player.vimeo.com/video/138623678?color=b50067&title=0&byline=0&portrait=0" width="640" height="360" frameborder="0" allow="autoplay; fullscreen; picture-in-picture" allowfullscreen=""></iframe> --- ## Analyse de requêtes HTTP Avec un navigateur web, il est possible d'analyser les requêtes envoyées par le client et les réponses reçues par le serveur. Le plus souvent, un clic droit, inspecter, réseau vous amènera au Moniteur réseau de votre navigateur --- ### A toi de jouer Effectue l'analyse d'une requête effectuée à l'URL suivante : http://glassus1.free.fr/interesting.html --- ### Quelques explications  --- ###### 1 **Méthode** de la requête, nous y reviendrons par la suite, et un code correspondant à l'**état** de la requête. Ici, on a reçu une réponse `200 OK`, ce qui signifie que la requête a été traitée et que la réponse contenant la page a été envoyée. Vous pouvez trouver à l'adresse [ici](https://developer.mozilla.org/fr/docs/Web/HTTP/Status) la totalité des états possibles. --- ###### 2 Taille totale des données transférées (388 octets) On voit que la réponse est constituée d'un **En-tête** (264 octets) qui contient : HTTP/1.1 200 OK Date: Wed, 22 Apr 2020 08:02:01 GMT Server: Apache/ProXad [Jan 23 2019 19:58:42] Last-Modified: Sun, 12 Apr 2020 16:39:55 GMT ETag: "15d7c75-7c-5e93445b" Connection: close Accept-Ranges: bytes Content-Length: 124 Content-Type: text/html --- Le **corps de la Réponse** (dont on sait d'après l'en-tête qu'il pèse 124 octets). Ce corps de la réponse est la charge utile de la réponse. Elle contient ici le code html de la page : <!DOCTYPE html> <html> <head> <title>Waouh</title> </head> <body> Ceci est vraiment une jolie page web. </body> </html> --- ## Variante HTTPS Le protocole **HTTP** n'est pas sécurisé par défaut, il peut l'être par l'ajout du protocole SSL ou TLS et on désigne par **HTTPS** sa version sécurisée. --- ## HTML, CSS et Javascript En pratique, d'autres types de ressources sont accessibles sur le Web par une **URL** : des images, des fichiers de données (aux formats CSV, JSON ...), des videos ... Par ailleurs les pages sont désormais réalisées en combinant **HTML** avec **CSS** pour la mise en forme, le positionnement, certains effets visuels et **Javascript** pour la programmation événementielle nécessaire à l'interactivité côté client. ----- # Le langage HTML ### Le contenu <img src="https://upload.wikimedia.org/wikipedia/commons/6/61/HTML5_logo_and_wordmark.svg" height='200px'> --- <iframe src="https://player.vimeo.com/video/138623721?h=7c5ddc9a0a&color=fc535c&title=0&byline=0&portrait=0" width="640" height="360" frameborder="0" allow="autoplay; fullscreen; picture-in-picture" allowfullscreen></iframe> --- <iframe src="https://player.vimeo.com/video/138623756?h=7162dfde21&color=fc535c&title=0&byline=0&portrait=0" width="640" height="360" frameborder="0" allow="autoplay; fullscreen; picture-in-picture" allowfullscreen></iframe> --- ### Un langage de balise Une page web **est un fichier contenant du texte**, ce texte étant enrichi par un système de **balises ouvrantes** - par exemple ```<p>``` et **fermantes** - par exemple `</p>`, permettant de donner un sens particulier (autrement dit une *sémantique*) au texte encadré par ces balises (titres, chapitres, paragraphes, illustrations...). --- Le langage utilisé qui contient le texte et les balises s'appelle `HTML` ( d'où le nom de l'extension de fichier `.html`), qui est un acronyme pour *Hyper Text Markup Language*, soit langage de balisage hypertexte. HTML *n'est pas un langage de programmation*, mais simplement un langage de description du texte, privilégiant la mise en avant du sens avant la forme. --- Il existe de nombreux langages de balisages, permettant de donner une forme particulière à du texte ou à des chaines de caractères. Par exemple, `HTML` pour le Web, $\LaTeX$ pour les documents scientifiques et les formules mathématiques, `XML` pour organiser des données, ou même `Markdown`, utilisé dans les Notebooks et pour la conception de ce site. --- Un fichier `html` se présente donc sous la forme suivante : ```html <!DOCTYPE html> <html lang="fr"> <head> <meta charset="utf-8" > <title>Une simple page web 🦁 </title> </head> <body> <h1>Ma première page web</h1> <h2>Le code html</h2> <!-- ceci est un commentaire comme en Python, il n'est pas interprété par le navigateur, et n'est là que pour les codeurs ou les curieux --> <p> Pour faire une page web, il faut taper du code <strong>HTML</strong>. <p> Afin de faire fonctionner celui-ci, il faut placer des <strong>balises</strong> qui encadrent des portions du texte : </p> <ul> <li> Une balise ouvrante, utilisant les symboles < et > , qui encadrent un mot clé ;</li> <li> Une balise fermante, identique à la balise ouvrante, mais un slash / précède le mot clé ;</li> <li> éventuellement des <strong>attributs</strong> viennent compléter le mot clé, afin de préciser un peu plus la balise, par exemple en donnant un identifiant particulier, ou l'url d'un lien.</li> </ul> <h2> Les différentes balises</h2> <p> Il existe de nombreuses balises en HTML. On peut trouver des explications sur leur fonctionnement en suivant <a href="https://developer.mozilla.org/fr/docs/Apprendre/HTML/Balises_HTML">ce lien</a></p> <p> Une autre possibilité est de télécharger la fiche suivante (une cheat sheet) : </p> <img src = "https://media.cheatography.com/storage/thumb/rmathieu13_html.750.jpg" alt ="Image de cheat sheet HTML" title="Cheat Sheet HTML" > </body> </html> ``` --- ### Intérêt des pages HTML Les pages HTML sont interprétées par des navigateurs qui sont dorénavant présents sur la plupart des appareils numériques. Ce qui en fait un format universel. Afin de s'adapter à toutes les tailles d'écran les pages web doivent-être **Responsive Web Design** --- L'objectif de ce cours est de te familiariser avec le langage HTML pour pouvoir créer ta page web étape par étape. --- #### Édition de fichiers `.html` Pour l'édition de fichier de type `.html`, il ne faut **surtout pas** utiliser un traitement de texte classique, comme Word ou LibreOffice. En effet ceux-ci rajoutent de manière cachée des informations dans le fichier en édition, ce qui risque de présenter de sérieux problèmes lors de l'affichage de la page web par un navigateur. --- Il est donc conseillé d'utiliser l'`éditeur de texte` dans chaque distribution Linux, ou le logiciel `Notepad++` sur Windows. Pour une utilisation avancée, vous pourrez utiliser un outil plus complet, comme `VSCodium` ou d'autres IDE spécialisés dans le développement web. --- Pour la suite de cette activité, on pourra simplement utiliser l'éditeur ci-dessous, y faire des copier/coller et visualiser le résultat en direct. --- ## Activité 1 : une première page web 1. Copiez dans le corps du fichier `index.html` le contenu HTML présenté au dessus. 2. Identifier le rôle des balises présentes dans ce document ? --- ## Structure d'un fichier HTML Tous les fichiers HTML doivent respecter cette structure : ``` html <!-- Ceci est un commentaire --> <!DOCTYPE html> <!-- définit le type de langage utilisé : ici le HTML --> <html lang="fr"> <!-- ouverture du bloc "html" - Langue : français --> <head> <!-- contenu du bloc "head" --> </head> <body> <!-- contenu du bloc "body" --> </body> </html> <!-- fermeture du bloc "html" --> ``` --- - **`<!DOCTYPE HTML>`** précise que le ficher contient du HTML - **`<html lang="fr">`** ouverture du bloc `html` qui englobe tout - **Bloc `<head>`** : entête. Contient la configuration de la page html - **Bloc `<body>`** : corps de la page. Contient toutes les informations à afficher. --- ### Le bloc `head` Entête Configuration de la page html --- #### Les balises d'entête ``` html <head> <title>Spécialité NSI</title> <meta charset="UTF-8"/> <link rel="stylesheet" href="css/style.css"/> <link rel="icon" type="image/png" href="images/favicon.png"/> <script src="js/script.js"> </script> </head> ``` --- - **`<meta charset="utf-8"/>`** définit l’encodage des caractères (affichage correct des lettres accentuées). - **`<title>Spécialité NSI</title>`** définit le nom de la page dans l’onglet du navigateur. - **`<link rel="stylesheet" href="css/style.css"/>`** indique l’utilisation d’une feuille de style et son chemin d'accès. - **`<link rel="icon" type="image/png" href="images/favicon.png"/>`** affiche une icone à gauche de l'onglet. - **`<script src="js/script.js"></script>`** indique l’utilisation d’un script de type JavaScript et son chemin d'accès. --- ### Le bloc `body` Corps de la page. Contient toutes les informations à afficher. --- #### Les balises de structure - **`<nav>`** contient la navigation dans le site. - **`<header>`** et **`<footer>`** définit l’entête et le pied de page. - **`<section>`**, **`<article>`** et **`<aside>`** organisent les différentes parties spécifiques à la page. - **`<div>`** balise générique qui définit un bloc sans lui donner de sens particulier. En général on lui donne un attribut d’identifiant **`id`** ou de classe **`class`** auquel on associe des propriétés d'affichage dans la feuille de style. --- #### Les balises de texte Il existe deux catégories de balise: - les balises de type `bloc` qui force le passage à la ligne avant et après le bloc. - les balises `inline` qui autorise le positionnement sur la même ligne. --- ##### Balises `block` - **`<h1>`**, **`<h2>`**, **`<h3>`**,**`<h4>`**, **`<h5>`** et **`<h6>`** : balises `bloc` pour les titres du texte. - **`<p>`** balise `bloc` qui définit un paragraphe (espace avant et après le texte). --- ##### balises `inline` : - **`<em>`**, (emphasis) pour mettre en valeur (italique), - **`<strong>`**, pour mettre en valeur (gras), - **`<code>`**, pour afficher du code informatique, - **`<sup>`**, pour mettre du texte en exposant, - **`<sub>`**, pour mettre du texte en indice, - **`<span>`**, balise générique, comme la balise **`div`** mais de type `inline`. Les propriétés associées sont à définir dans la feuille de style. --- #### Exemple de rendu de balises de texte ``` html <body> <h1>Titre de niveau 1</h1> <h2>Titre de niveau 2</h2> <h3>Titre de niveau 3</h3> <h4>Titre de niveau 4</h4> <h5>Titre de niveau 5</h5> <h6>Titre de niveau 6</h6> <p> Ceci est un paragraphe. Il force le passage à la ligne et met en place des espacements avec les éléments au dessus et au dessous (margin et padding). </p> <p> Mise en place des balises in-line : <em>emphasis</em>, <strong>strong</strong>, <code>code</code> <sup>sup</sup>, <sub>sub</sub> et <span style="color:red"> span</span> : balise générique - (pas de propriétés par défaut) </p> </body> ``` --- #### Les listes : 2 types de liste - les listes non numérotées , introduites par **`<ul>`**, - les listes numérotées , introduites par **`<ol>`**, - Chaque item d'une liste sont introduit par **`<li>`**. --- #### Exemple de listes ``` html <body> <h1> Faire une pâte à crêpe </h1> <h2> Liste des ingrédients </h2> <ul> <li> 500g de farine </li> <li> 2 oeufs </li> <li> 0,5l de lait </li> <li> une pincée de sel </li> </ul> <h2> préparation </h2> <ol> <li> Mélanger les ingrédients </li> <li> Laisser reposer </li> <li> Faire chauffer la poêle </li> </ol> </body> ``` --- #### Les tableaux avec entête - **`<table>`** déclare le tableau, - **`<tr>`** (table row) définit une ligne du tableau, - **`<th>`** (table header) définit une cellule d'entête du tableau. - **`<td>`** (table data) définit une cellule de donnée du tableau. --- #### Exemple de tableau ``` html <body> <table> <tr> <th> Prénom </th> <th> Nom </th> <th> Age </th> </tr> <tr> <td> Alain </td> <td> Térieur </td> <td> 50 </td> </tr> <tr> <td> Paul </td> <td> Auchon </td> <td> 94 </td> </tr> <tr> <td> Jean </td> <td> Raffole </td> <td> 80 </td> </tr> </table> </body> ``` --- #### Les liens hypertextes La balise **`<a>`** définit un lien hypertexte. - On peut définir une URL comme lien : description d'un chemin absolu. ``` html <a href="https://nsi.lycee-experimental.org/"> Site 1NSI du lycée PGDG </a> ``` - On peut définir un chemin relativement au répertoire courant : description d'un chemin relatif. ``` html <a href="../page1.html"> Aller vers la page1 </a> ``` - On peut valider le lien en cliquant sur une image. ``` html <a href="https://nsi.lycee-experimental.org/"><img src="../img/smiley.jpg" alt="Smiley pour tuto HTML"> </a> ``` - On peut faire apparaît un label lors du survol du lien. ``` html <a href="https://nsi.lycee-experimental.org/" title="Site 1NSI du lycée PGDG"> 1NSI </a> ``` --- ## Activité 2 : A vous de jouer Créez une page web sur le sujet de ton choix, et qui respecte au moins les conditions suivantes : 1. Un titre et au moins 2 sous-titres 2. Deux parties de 3 paragraphes, avec au moins une liste (numérotée ou non). 3. Un lien externe à la page 4. De la mise en forme avec des `éléments inline` 4. Un tableau 5. une image distante (par URL, clic droit puis copier l'adresse de l'image) ----- ## Formulaires HTML <img src='/assets/images/form.png' height='200px'> --- En HTML, un formulaire est un élément qui permet de transmettre des informations à un serveur Web. Il est composé d'un élément `<form action="http://domaine/cible" method="GET" >` qui contient un ou plusieurs widgets, des éléments HTML permettant de saisir les entrées du client et au moins un élément `<button type="submit>Bouton d'envoi</button>`. --- ### Exemple ```html <!DOCTYPE html> <html lang="fr"> <head> <title>Formulaire HTML </title> <meta charset="utf-8"> </head> <body> <form action = "accueil.php" method="GET"> <label for="id_prenom">Prénom :</label> <input type="text" id="id_prenom" name="prenom" value="Alan"> <label for="id_nom">Nom :</label> <input type="text" id="id_nom" name="nom" value="Turing"> <button type="submit" id="bouton">Envoyer</button> </form> </body> </html> ``` --- ### Rendu <form action = "accueil.php" method="GET"> <label for="id_prenom">Prénom :</label> <input type="text" id="id_prenom" name="prenom" value="Alan"> <label for="id_nom">Nom :</label> <input type="text" id="id_nom" name="nom" value="Turing"> <button type="submit" id="bouton">Envoyer</button> </form> --- ### Requêtes POST et GET Un clic sur ce dernier déclenche l'exécution d'une requête HTTP qui va transmettre les données saisies selon les valeurs des attributs `action` et `method` de l'élément `<form>` --- ### Actions `action` a pour valeur l'**URL** du fichier auquel sera envoyé le formulaire. Ce fichier est un programme écrit dans un langage de script comme PHP ou Python, qui va prendre en entrée les paramètres du formulaire transmis par le client, les traiter et générer la page Web en **HTML** qui lui sera renvoyée. --- ### Méthodes `method` peut prendre deux valeurs **GET** ou **POST** (en minuscule ou majuscule), ce sont les deux modes de transmission des paramètres du formulaire qui sont deux méthodes distinctes du protocole **HTTP** : * avec la méthode **GET** , les données du formulaire sont assemblées dans une chaîne de paires `nom=valeur` séparées par le symbole `&` qui est ajoutée à la fin de l'**URL** après le délimiteur `?`. * avec la méthode **POST** les données du formulaire sont toujours transmises dans le corps de la requête. Les données n'apparaissent donc pas dans l'**URL**. --- Le formulaire de l'exemple contient deux widgets `<input>`. Chacun va fournir un couple `nom=valeur`, le nom est désigné par l'attribut `name` et la valeur par le texte saisi dans l'élément `<input>`. Chacun est associé par son attribut `id` à une étiquette contenue dans un élément `<label>`. --- #### Méthode **GET** * Toutes les informations transmises, le sont en clair dans l'**URL**. Celle-ci est limitée en taille donc la méthode **GET** ne peut pas être utilisée pour transmettre des informations trop longues. * Une requête **GET** est constituée uniquement d'un entête, elle n'a pas de corps. * Elle ne modifie pas l'état du serveur, elle est utilisée uniquement pour demander une ressource. Un exemple classique d'utilisation est la formulation d'une requête à l'aide du formulaire d'un moteur de recherche. L'**URL** générée peut être utilisée plusieurs fois et conservée comme marque-page. --- Observation des paramètres envoyés par une requête **GET** (`?nom=turing&prenom=Alan`)   --- #### Méthode **POST** * Les données sont transmises dans le corps de la requête, il n'y a pas de restriction de taille. Elles peuvent être de tout type : url-encodées (chaîne de paires `nom=valeur`), ou binaires. C'est précisé dans le champ `Content-type` de l'entête comme pour une réponse **HTTP**. * Les données n'apparaissent pas dans l'**URL**, néanmoins, si le protocole **HTTP** est employé sans chiffrement, il suffit d'intercepter la requête pour accéder aux données en clair. * Les données envoyées peuvent modifier l'état du serveur. Par exemple, les requêtes **POST** sont utilisées pour les modifications de bases de données sur le serveur (achats, réservation, transfert de fichiers ...). Par conséquent si on veut renvoyer les données d'un formulaire, un message en popup avertit que ce nouvel envoi peut modifier l'état du serveur et par exemple d'enregistrer un nouvel achat s'il s'agit d'un formulaire de commande. --- Observation des paramètres envoyés par une requête **POST**   --- ## A toi de jouer Analyse par toi-même les requêtes effectuées avec [GET](http://frederic-junier.org/NSI/sandbox/formulaire-get.html) et [POST](http://frederic-junier.org/NSI/sandbox/formulaire-post.html) sur ton navigateur. - Clic droit, inspecter, réseau ou - Moniteur réseau de Firefox : `CTR+SHIFT+E` --- ### Principaux éléments d'un formulaire --- #### `<label>` Permet d'ajouter des étiquettes pour renseigner le champs du formulaire. ```html <label for="id_prenom">Prénom :</label> <input type="text" id="id_prenom" name="prenom" value="Alan"> ``` **Rendu** <label for="id_prenom">Prénom :</label> <input type="text" id="id_prenom" name="prenom" value="Alan"> --- #### `<input>` Principal élément permettant la saisie de données dans un champ de formulaire [HTML][HTML]. Son attribut `type` permet de vérifier que les données saisies correspondent au type attendu. --- ##### Texte ```html <input type="text" name="t" value="Défaut"> ``` **Rendu** <input type="text" name="t" value="Défaut"> --- ##### Email ```html <input type="email" name="a" value="defaut@defaut.fr"> ``` **Rendu** <input type="email" name="a" value="defaut@defaut.fr"> --- ##### Nombre | ```html <input type="number" name="n" value="1" min="0" max="10"> ``` **Rendu** <input type="number" name="n" value="1" min="0" max="10"> --- ##### Mot de passe | ```html <input type="password" name="pwd"> ``` **Rendu** <input type="password" name="pwd"> --- ##### Cases à cocher ```html <input type="checkbox" name="carrots" value="carrots"> ``` **Rendu** <input type="checkbox" name="carrots" value="carrots"> --- ##### Bouton radio (choix exclusif) ```html <input type="radio" value="soup" name="meal"> ``` **Rendu** <input type="radio" value="soup" name="meal"> --- ##### `<textarea>` L'élément `<textarea>` permet de saisir un texte de longueur arbitraire et `<select>` permet de définir une liste déroulante. ```html <textarea name="ici">Ecrire ici </textarea> ``` **Exemple :** <textarea name="ici">Ecrire ici</textarea> --- #### Les boutons `<button>` Le bouton de soumission d'un formulaire : ```html <button type="submit">Envoyer</button>`. ``` **Exemple :** <button type="submit">Envoyer</button> --- #### A toi de jouer Réalise un formulaire d'inscription au Lycée Expérimental, et envoie les données avec la méthode **GET** à l'**URL** `https://lycee-experimental.org` --- ## Ressources Cette page de [Mozilla](https://developer.mozilla.org/fr/docs/Web/Guide/HTML/Formulaires/Les_blocs_de_formulaires_natifs) décrit les principaux widgets de formulaire et cette page de [W3schools](https://www.w3schools.com/html/html_form_elements.asp) permet de les tester. ----- # Le langage CSS ### L'apparence <img src="https://upload.wikimedia.org/wikipedia/commons/d/d5/CSS3_logo_and_wordmark.svg" height="200px"> --- Le HTML définit donc le **contenu** de la page. Le CSS en définit l'**apparence** (le style). --- <iframe src="https://player.vimeo.com/video/138623826?h=d08fcbd851&color=fc535c&title=0&byline=0&portrait=0" width="640" height="360" frameborder="0" allow="autoplay; fullscreen; picture-in-picture" allowfullscreen></iframe> --- 3 façons de d’appliquer un style à une balise : - dans la balise elle-même en utilisant l’attribut style, - dans le bloc `<head>` du code html à l’aide d’une balise `<style>`, - à part, dans un fichier ayant une extension `*.css` **➤ à privilégier**. --- ### CSS : les sélecteurs Les sélecteurs `css` ciblent les éléments HTML auxquels on va attribuer des propriétés. --- #### Sélecteurs | Type de sélecteur | Exemple | Description | | :--: | :--: | :--: | | `balise` | `p` | Sélectionne toutes les balises `<p>` | | `.class` | `.intro` | Sélectionne toutes les balises contenant l’attribut `class="intro"` | | `#id` | `#date` | Sélectionne la balise contenant l’attribut `id=“date"` | --- ##### Combinaisons | Type de sélecteur | Exemple | Description | | :--: | :--: | :--: | | `sélecteur, sélecteur` | `div, p` | Sélectionne les 2 sélecteurs (balises `<div>` et `<p>`) | | `balise balise` | `div p` | Sélectionne toutes les balises `<p>` contenues dans les balises `<div>` | | `balise.class` | `p.intro` | Sélectionne les balises `<p>` contenant l’attribut `class="intro”` | --- #### Exemple d'utilisation Fichier `index.html` ``` html <!DOCTYPE html> <html lang="fr"> <head> <meta charset="utf-8" /> <link rel="stylesheet" href="style.css" /> </head> <body> <div id="page"> <p> ceci est le bloc div - balise p dans div </p> <h1 class="intro"> balise h1 classe intro </h1> </div> <h2> balise h2 </h2> <h3> balise h3 </h3> <p class="intro"> balise p classe intro </p> </body> </html> ``` --- Fichier `style.css` ``` css h2 { font-size: 2em; } #page { color:blue; background-color : lightblue; } .intro { text-align: center; } h2, h3 { font-style:italic; font-family: arial; } div p { text-decoration: underline; } p.intro { color : maroon; font-weight: bold; text-decoration: line-through } ``` --- ### Liste de propriétés CSS --- #### Quelques propriétés CSS dédiées au texte | Nom de la propriété | Valeurs possibles | Remarque | | :--: | :--: | :--: | | `color` | Code couleur | Définit la couleur du texte | | `background-color` | Code couleur | Définit la couleur de fond de l'élément HTML | | `font-family` | Nom de la police de caractère | Définit la police à utiliser | | `font-size` | Valeur numérique | Définit la taille de la police | | `font-style` | `normal`, `italic` ou `oblique` | | | `font-weight` | `normal` ou `bold` | `bold` affiche les caractères en **gras** | | `text-decoration` | `None`, `line-through` ou `underline` | | | `line-height` | Valeur numérique | Définit la hauteur minimale de la ligne | | `text-indent` | Valeur numérique | Définit l'indentation (c'est à dire le retrait de la 1ère ligne) | --- #### Quelques propriétés dédiés aux blocs | Propriété | Valeurs possibles | Remarque | | :--: | :--: | :--: | | `margin` | Valeur numérique | Définit l'épaisseur de la marge extérieure | | `padding` | Valeur numérique de caractère | Définit l'espace entre le contenu et la bordure (marge intérieure) | | `border-width` | Valeur numérique (0 par défaut) | Définit l'épaisseur de la bordure | | `border-style` | `solid`, `dashed`, `dotted`, `groove` ou `ridge`, par défaut `None` | Définit le style de la bordure | | `border-color` | Code d'une couleur | Définit la couleur de la bordure | | `border-radius` | Valeur numérique | Définit le rayon de l'arrondi des coins du cadre | | `border` | `width` `style` `color` | Définit la largeur, le style et la couleur en une seule fois | --- #### Exemple Fichier `index.html` ``` html <!DOCTYPE html> <html lang="fr"> <head> <meta charset="utf-8" /> <link rel="stylesheet" href="style.css" /> </head> <body> <table> <tr> <td> <img id="photo1" src="./img/vacances1.jpg" alt="Vacances à la mer" title="Vacances à la mer"> </td> <td> <h1 id="titre"> Mes belles vacances </h1> </td> <td> <img id="photo2"src="./img/vacances2.jpg" alt="Vacances à la montagne"> </td> </tr> </table> </body> </html> ``` --- Fichier `style.css` ``` css td { border: 1px dotted black; } #titre { border: 20px solid lightblue; border-style: outset; padding:40px; margin:20px; } #photo1 { border: 15px solid lightgrey; border-radius : 50px; margin-left: 30px; } #photo2 { border: 5px dashed blue; border-radius: 50%; padding:10px; margin-right:30px; } ``` --- #### Les pseudo-classes Les pseudo-classes sont utilisées pour cibler un état particulier pour un élément. | La pseudo-classe | Exemple | Description | | :--: | :--: | :--: | | `:link` | `a:link { color:bleu; }` | Sélectionne le lien non visité | | `:visited` | `a:visited { color:red; }` | Sélectionne le lien visité | | `:hover` | `a:hover { color:hotpink; }` | Sélectionne le lien survolé par la souris | | `:active` | `a:active { color:green; }` | Sélectionne le lien actif | | `:focus` | `input:focus` | Sélectionne la balise `<input>` ayant le focus | | `:required` | `input:required` | Sélectionne les balises `<input>` à remplir obligatoirement | Voir l'exemple d'utilisation sur le site de [W3schools.com](https://www.w3schools.com/css/css_pseudo_classes.asp). --- ## Liens utiles [Mozilla : commencer avec le web](https://developer.mozilla.org/fr/docs/Learn/Getting_started_with_the_web) [Khan-academy : un tuto pour les personnes qui débutent](https://fr.khanacademy.org/computing/computer-programming/html-css) [Ostralo.net : Une synthèse](http://numerique.ostralo.net/html_css) [W3school : pour retrouver une information ou tester un exemple.](https://www.w3schools.com) ----- # Le langage Javascript ### L'interaction <img src="https://upload.wikimedia.org/wikipedia/commons/d/d4/Javascript-shield.svg" height="200px"> --- ## Présentation JavaScript a été créé en 1995 par Brendan Eich. Il a été standardisé sous le nom d'ECMAScript en juin 1997 par Ecma International dans le standard ECMA-262. --- JavaScript est un **langage de programmation** principalement employé dans les pages web en complètement de HTML et CSS pour les rendre **interactives** (réaction de la page web aux interventions de l'utilisateur). Il permet d'écrire des scripts : c'est un langage interprété par le navigateur, coté client. --- ## Le DOM : Documents Object Model Afin de pouvoir intervenir sur la page web, tous les éléments de cette page sont utilisés en tant qu'objets agencés suivant l'**arborescence** de la page HTML. La racine de cet arbre s'appelle **`document`**. --- <img src="https://upload.wikimedia.org/wikipedia/commons/5/5a/DOM-model.svg" height='100%'> --- Le **DOM** est une interface de programmation HTML qui définit : - les éléments HTML en tant qu'**objets**, - les **propriétés** de tous les éléments HTML, - les **méthodes** pour accéder à tous les éléments HTML, - les **événements** pour tous les éléments HTML. **HTML DOM est un standard qui définit comment accéder, changer, ajouter ou supprimer des éléments HTML**. --- ## Différentes possibilités de sélection des éléments : - Sélection d'un élément par l'arborescence du DOM . `document.title = "Le JavaScript";` - Sélection d'un élément par l'attribut `id`. Par définition un `id` n'est associé qu'à un seul élément. `document.getElementById('bloc_page').style.width = '250px';` - Sélection de tous les éléments par l'attribut `class`. Le résultat est un tableau[^1] des différents éléments. `let imagesflottantes = document.getElementsByClassName("imagesflottantes");` - Sélection de tous les éléments par le nom de balise. Le résultat est un tableau[^1] des différents éléments. `let paragraphes = document.getElementsByTagName('p');` - Sélection d'un élément (le 1er si il y en a plusieurs) en reprenant la syntaxe des sélecteurs CSS. `document.querySelector("#bloc_page").style.backgroundColor = 'lightgrey';` - Sélection de plusieurs éléments en reprenant la syntaxe des sélecteurs CSS : le résultat est dans un tableau[^1]. `document.querySelectorAll("p.important")[0].style.backgroundColor = 'gold';` --- #### Exemple de sélection d'éléments Fichier `index.html` ``` html <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>Premier test du HTML</title> </head> <body> <div id="bloc_page"> <h1>Mon super site</h1> <img src="./img/js100.png" class="imagesflottantes" alt="Logo JavaScript" /> <p class="important">Bonjour et bienvenue sur mon site !</p> <p>Pour le moment, mon site est un peu vide.</p> <p><a href="http://pgdg.frama.io/1nsi">cours de 1NSI</a></p> <script src="script.js"></script> </div> </body> </html> ``` **Remarque :** Le script est placé à la fin du fichier HTML car il ne peut accéder aux propriétés des éléments que s'ils existent... --- Fichier `script.js` ``` js // Accès aux élément par l'arborescence du DOM document.title = "Le JavaScript"; document.body.style.color = 'purple'; // Sélection de l'élément ayant pour identifiant "bloc_page" et modification de sa largeur // Par définition id ne correspond qu'à un seul élément. document.getElementById('bloc_page').style.width = '250px'; // Sélection de tous les éléments ayant un attribut class="imagesflottantes" let imagesflottantes = document.getElementsByClassName("imagesflottantes"); // Les éléments sont référencés dans un tableau : on y accède avec une boucle for for (image of imagesflottantes) { image.style.float = 'right'; } // Accès aux éléments par le nom de balise let paragraphes = document.getElementsByTagName('p'); // Les éléments sont référencés dans un tableau : on y accède avec une boucle for for (paragraphe of paragraphes) { paragraphe.textContent = 'Je suis un paragraphe'; } // Accès aux éléments à l'aide des sélecteurs CSS // `querySelector` sélectionne un seul élément (le 1er si il y en a plusieurs) document.querySelector("#bloc_page").style.backgroundColor = 'lightgrey'; // `querySelectorAll` sélectionne plusieurs éléments : le résultat est dans un tableau document.querySelectorAll("p.important")[0].style.backgroundColor = 'gold'; ``` --- ## Comparaison des syntaxes entre Python et JavaScript On retrouve les mêmes structures de base dans tous les langages informatiques, mais la syntaxe varie. Comme beaucoup d'autres langages, la syntaxe de JavaScript provient du langage C (avec des spécificités). --- ### Les commentaires en JavaScript ``` js y = 2*n; // Ceci est un commentaire sur le reste de la ligne /* Ceci est un commentaire sur plusieurs lignes */ ``` --- ### Les variables Contrairement à python, les variables utilisées en JavaScript doivent être déclarées. ``` js var variable1, variable2 = "exemple"; // domaine d'existence limité à la fonction où elle sont déclarées. let variable3; // domaine d'existence limité au bloc où elle est déclarée. const vitesseLumiere = 3e8; // définit une constante (qu'on ne peut pas modifier par la suite). variable2 = "exemple2"; // affectation d'une nouvelle valeur à variable2 ``` De manière générale, on préfère l'utilisation de `let` ou `const` à l'utilisation de `var` qui date des tous débuts de JavaScript. --- #### Utilisation de variable Fichier `index.html` ``` html <p id="accueil"> </p> <script> let prenom = "Pierre"; document.getElementById("accueil").innerHTML = "Bonjour <em>" + prenom + "</em>"; </script> ``` --- ### Instructions conditionnelles Python ``` Python if blue: blue = false else: blue = true ``` Javascript ``` js if (blue) { blue = false; } else { blue = true; } ``` </td><td> --- ##### Remarques - Un bloc d’instructions est défini entre **accolades**. - Les conditions sont écrites entre **parenthèses**. - Toutes les instructions se terminent par un **point virgule** (pas obligatoire en JS mais obligatoire en C). - L’**indentation** n’est pas nécessaire pour l’interpréteur mais imposée pour permettre une bonne lecture du programme. --- ### Boucles for Python ``` python for n in range(10): y = 2*n ``` Javascript ``` js for(let n=0 ; n<10 ; n++) { y = 2*n; } ``` --- ##### Remarques La boucle `for` est constituée de 3 champs : - 1er champ : valeur de la variable de boucle avant d'entrer dans la boucle - 2ème champ : condition pour rester dans la boucle - 3ème champ : instruction exécutée à la fin de chaque boucle --- ### Listes et tableaux Python ``` python liste = [1,3,5,9,12] for n in liste: y = 2*n ``` Javascript ``` js let tableau = [1,3,5,9,12] for (let n of tableau) { y = 2*n; } ``` --- ##### Remarques - En python on parle de `list`, contrairement à tous les autres langages où on parle de tableau (`Array`) - Utilisation de `in` en python, de `of` en JavaScript --- ### Booléens Python ``` python if True and not(False or True): print("coucou") ``` Javascript ``` js if (true && !(false || true)) { console.log("coucou") } ``` --- ##### Remarques - `true` et `false` sans majuscule en JavaScript - Les opérateurs booléens sont très différents --- ## Détection des évènements du DOM : DOM events Les événements - event - auxquels peut réagir javascript sont de plusieurs types. - événements de la souris - événements de la clavier - événements du navigateur (input, chargement...) - etc... --- ### Réaction aux évènements de la souris | Événements | Description | Exemple d'utilisation | | :-- | :-- | :-- | | `onclick` | Le clic de la souris sur un élément | `<h1 onclick="this.innerHTML = 'Ooops!'">Click on this text!</h1> ` | | `ondblclick` | Le double-clic de la souris sur un élément | `<h1 onclick="this.innerHTML = 'Ooops! Ooops!'">Click on this text!</h1> ` | | `onmouseover` | Le survol de la souris sur un élément | `<div onmouseover="this.style.backgroundColor = 'lightblue'">`| | `onmouseout` | La sortie de la souris d'un élément | `<div onmouseout="this.style.backgroundColor = 'yellow'">`| | `onmousedown` | Le maintien du clic appuyé sur un élément | `<div onmousedown="this.style.color = 'white'">` | | `onmouseup` | Le relachement du clic de souris | `<div onmouseup="this.style.color = 'blue'">` | --- ### Réactions aux évènements sur les `<input type="text"/>` | Événements | Description | Exemple d'utilisation | | :-- | :-- | :-- | | `onfocus` | Positionnement du curseur dans le `input` | `<input type="text" onfocus="this.style.border='solid 2px maroon"> ` | | `onselect` | Sélection du contenu de la saisie | `<input type="text" onselect="this.style.color = 'red'"> ` | | `onblur` | Sortie du champ du `input` | `<input type="text" onblur="this.style.backgroundColor = 'grey'">` | | `onkeydown` | Le maintien d'une touche clavier appuyée | `<div onkeydown="this.style.borderStyle = 'dashed'">` | | `onkeyup` | Le relâchement de la touche clavier | `<div onkeyup="this.style.borderStyle = 'double'">` | | `onchange` | Changement d'option sur une liste déroulante | [Voir l'exemple](https://www.w3schools.com/JS/tryit.asp?filename=tryjs_events_dropdown) | --- ### Réactions au chargement de pages ou d'images | Événements | Description | Exemple d'utilisation | | :-- | :-- | :-- | | `onload` | Quand la page (ou l'image) est chargée | `<body onload="checkCookies()"> ` | | `onerror` | lors d'une erreur de chargement d'une image | [Voir l'exemple](https://www.w3schools.com/JS/tryit.asp?filename=tryjs_events_onerror) | | `onunload` | Lors de la fermeture de la page | [Voir l'exemple](https://www.w3schools.com/JS/tryit.asp?filename=tryjs_events_onunload) | | `onresize` | Changement d'option sur une liste déroulante | [Voir l'exemple](https://www.w3schools.com/JS/tryit.asp?filename=tryjs_events_onresize) | --- #### Essayer par vous même Fichier `index.html` ```html <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>Les évènements en Javascript</title> </head> <body> <div id="bloc_page" onmouseover="this.style.backgroundColor = 'yellow'" onmouseout="this.style.backgroundColor = 'lightblue'" onmousedown="this.style.color = 'white'" onmouseup="this.style.color = 'blue'"> <h1 onclick="this.innerHTML = 'Ooops!'" ondblclick="this.innerHTML = 'Ooops! Ooops!'">Mon super site</h1> <p>Zone de saisie de type <code> input type="text"</code> : </p> <input type="text" onfocus="this.style.border='solid 4px maroon'" onselect="this.style.color = 'red'" onfocusin="this.style.backgroundColor = 'white'" onblur="this.style.backgroundColor = 'lightgrey'" onkeydown="this.style.borderStyle = 'dashed'" onkeyup="this.style.borderStyle = 'dotted'"> </div> </body> </html> ``` --- **Rendu du navigateur** Réaliser les différents évènements de souris et de clavier sur les différents éléments `<div>`, `<h1>` et `<input>`. <div id="bloc_page" style="background-color:lightgreen; padding:15px" onmouseover="this.style.backgroundColor = 'yellow'" onmouseout="this.style.backgroundColor = 'lightblue'" onmousedown="this.style.color = 'white'" onmouseup="this.style.color = 'blue'"> <h1 onclick="this.innerHTML = 'Ooops!'" ondblclick="this.innerHTML = 'Ooops! Ooops!'">Mon super site</h1> <p>Zone de saisie de type <code> input type="text"</code> : </p> <input type="text" style="border: 2px solid black;" onfocus="this.style.border='solid 4px maroon'" onselect="this.style.color = 'red'" onfocusin="this.style.backgroundColor = 'white'" onblur="this.style.backgroundColor = 'lightgrey'" onkeydown="this.style.borderStyle = 'dashed'" onkeyup="this.style.borderStyle = 'dotted'"> </div> --- ## Gestion des évènements : `AddEventListener()` Il existe 3 façons d'implémenter un gestionnaire d'évènements: - Utilisation d'un attribut HTML. Par exemple : `<button type="button" onclick="modifierTitre1()">Cliquer ici</button>` - Utilisation des propriétés JavaScript. Par exemple : `document.getElementById('validation').onclick = calculValeurAuCarre;` - Utilisation de la méthode `addEventListener()`. Par exemple : `document.getElementById('validation').addEventListener("click", calculValeurAuCarre);` --- ### Implémentation de gestionnaire d'évènements --- #### Utilisation d'un attribut HTML ```html <script> function modifierTitre1() { document.getElementById("titre1").innerHTML = "Titre Cliqué"; } </script> <h1 id="titre1"> Mon Titre1 </h1> <button type="button" onclick="modifierTitre1()">Cliquer ici</button> ``` <script> function modifierTitre1() { document.getElementById("titre1").innerHTML = "Titre Cliqué"; } </script> <h1 id="titre1"> Mon Titre1 </h1> <button type="button" onclick="modifierTitre1()">Cliquer ici</button> --- #### Utilisation des propriétés JavaScript ```html <h1 id="resultat"> Saisir un nombre puis valider</h1> <input id='valeur' type="number" value="10"/> <button id="validation" type="button">Validation</button> <script> let valeur, carre; document.getElementById('validation').onclick = calculValeurAuCarre; function calculValeurAuCarre() { valeur = document.getElementById('valeur').value; carre = (parseInt(valeur)*parseInt(valeur)).toString(); document.getElementById('resultat').innerHTML = valeur + " au carré = " + carre; } </script> ``` <h1 id="resultat2"> Saisir un nombre puis valider</h1> <input id='valeur' type="number" value="10"/> <button id="validation" type="button">Validation</button> <script> let valeur, carre; document.getElementById('validation').onclick = calculValeurAuCarre; function calculValeurAuCarre() { valeur = document.getElementById('valeur').value; carre = (parseInt(valeur)*parseInt(valeur)).toString(); document.getElementById('resultat2').innerHTML = valeur + " au carré = " + carre; } </script> --- #### Utilisation de la méthode `addEventListener()` ``` html <h1 id="resultat"> Saisir un nombre puis valider</h1> <input id='valeur' type="number" value="10"/> <button id="validation" type="button">Validation</button> <script> let valeur, carre; document.getElementById('validation').addEventListener("click", calculValeurAuCarre); function calculValeurAuCarre() { valeur = document.getElementById('valeur').value; carre = (parseInt(valeur)*parseInt(valeur)).toString(); document.getElementById('resultat').innerHTML = valeur + " au carré = " + carre; } </script> ``` --- ## Les formulaires en JavaScript Un formulaire permet à un **client** (navigateur) de transmettre des données à un **serveur**. Le formulaire est le bloc qui organise la saisie des données et qui les envoie au serveur lors de sa validation (`submit`). Il est intéressant de gérer les formulaires avec JavaScript car il permet de traiter plus facilement les données envoyées par le formulaire. --- ### Formulaire simple en HTML Fichier `index.html` ```html <html> <head> <meta charset="utf-8" /> <title>Les formulaires en Javascript</title> </head> <body> <form action="https://nsi.lycee-experimental.org" target="_blank" method="POST"> <p>Input de type texte : <input type="text" name="saisie" placeholder="Saisir un texte"></p> <input type="submit" value="Validation"> </form> </body> </html> ``` **Rendu dans le navigateur** <div style="background-color:lightgreen; padding:15px"> <form action="https://nsi.lycee-experimental.org" target="_blank" method="POST"> <p>Input de type texte : <input type="text" name="saisie" placeholder="Saisir un texte"></p> <input type="submit" value="Validation"> </form> </div> --- **Commentaires :** - Le formulaire exécute l'`action` (accès à une nouvelle page) lors de l'appui sur le button de type `submit`. - Grâce à la méthode `POST` on peut récupérer la valeur (contenu de l'attribut `value`) des différents éléments contenus dans le formulaire à l'aide du nom de l'élément (attribut `name`). --- ### Formulaire simple en JS Fichier `index.html` ```html <html> <head> <meta charset="utf-8" /> <title>Les formulaires en Javascript</title> </head> <body> <form action="https://nsi.lycee-experimental.org" target="_blank" method="POST"> <p>Input de type texte : <input type="text" name="saisie" placeholder="Saisir un texte"></p> <input type="button" value="Validation" onClick="this.form.submit()"> </form> </body> </html> ``` **Rendu dans le navigateur** <div style="background-color:lightgreen; padding:15px"> <form action="https://nsi.lycee-experimental.org" target="_blank" method="POST"> <p>Input de type texte : <input type="text" name="saisie" placeholder="Saisir un texte"></p> <input type="button" value="Validation" onClick="this.form.submit()"> </form> </div> --- **Commentaires :** - Ce formulaire effectue la même chose que le formulaire HTML ci-dessus et présente donc peu d'intérêt. - Il permet d'introduire la méthode JavaScript spécifique aux formulaires : `submit()`. - Le mot clé `this` est une référence à l'objet en cours de manipulation. Il simplifie la syntaxe. --- #### Validation du formulaire par un clic sur une image Fichier `index.html` ```html <html> <head> <meta charset="utf-8" /> <title>Les formulaires en Javascript</title> </head> <body> <form id="formulaire" action="https://nsi.lycee-experimental.org" target="_blank" method="POST"> Input de type texte : <input id="saisie" type="text" name="saisie" placeholder="Saisir un texte"><br> <img src="https://upload.wikimedia.org/wikipedia/commons/6/66/SmileyFace.png" height="100px" onClick="validation_formulaire()"/> </form> <script> function validation_formulaire() { let formElement = document.getElementById('formulaire'); let elementValue = document.getElementById('saisie').value; alert("Valeur saisie : " + elementValue); formElement.submit(); } </script> </body> </html> ``` Tester le code en le copiant en dessous. --- **Commentaires :** - L'attribut `onClick` de la balise `img` appelle la fonction `validation_formulaire()`. - La variable `formElement` référence le formulaire : on lui applique la méthode `submit()`. - On peut profiter de la fonction pour faire d'autres traitements tel qu'afficher le contenu de la zone de saisie dans une boîte de dialogue `alert`. --- ### Envoi de données liées à la zone cliquée Très souvent, on souhaite exécuter le formulaire lors d'un clic sur différents éléments de la page et connaître coté serveur quel est l'élément cliqué. C'est par exemple nécessaire pour un jeu de morpion, de puissance4 ou de bataille navale, ... Dans ce cas, on crée un tableau HTML (`<table>`) correspondant à la grille de placement et on veut connaître la case cliquée coté serveur. --- #### Exemple d'un tableau 3x3 dont on veut connaître la case cliquée. Fichier `index.html` ```html <html> <head> <meta charset="utf-8" /> <title>Les formulaires en Javascript</title> </head> <body onload="auLancement()"> <form id="formulaire" action="https://nsi.lycee-experimental.org" target="_blank" method="POST"> <table id="table"> <tr><td id="0,0"> X </td> <td id="0,1"> O </td> <td id="0,2"> O </td> </tr> <tr><td id="1,0"> O </td> <td id="1,1"> X </td> <td id="1,2"> X </td> </tr> <tr><td id="2,0"> O </td> <td id="2,1"> X </td> <td id="2,2"> X </td> </tr> </table> <input id="hidden" type="hidden" name="case_cliquee" value=""/> </form> <script> function auLancement() { let formElement = document.getElementById('formulaire'); let table = document.getElementById("table"); let trs = table.getElementsByTagName("tr"); let tds = null; for (let tr of trs) { let tds = tr.getElementsByTagName("td"); for (let td of tds) { td.onclick=function() { alert(this.id); this.style.backgroundColor = 'red'; document.getElementById('hidden').value = this.id; formElement.submit(); } } } } </script> </body> </html> ``` --- <form id="formulaire" action="https://nsi.lycee-experimental.org" target="_blank" method="POST"> <table id="table"> <tr><td id="0,0"> X </td> <td id="0,1"> O </td> <td id="0,2"> O </td> </tr> <tr><td id="1,0"> O </td> <td id="1,1"> X </td> <td id="1,2"> X </td> </tr> <tr><td id="2,0"> O </td> <td id="2,1"> X </td> <td id="2,2"> X </td> </tr> </table> <input id="hidden" type="hidden" name="case_cliquee" value=""/> </form> <script> function auLancement() { let formElement = document.getElementById('formulaire'); let table = document.getElementById("table"); let trs = table.getElementsByTagName("tr"); let tds = null; for (let tr of trs) { let tds = tr.getElementsByTagName("td"); for (let td of tds) { td.onclick=function() { alert(this.id); this.style.backgroundColor = 'red'; document.getElementById('hidden').value = this.id; formElement.submit(); } } } } auLancement() </script> --- **Commentaires :** - `<body onload="auLancement()">` force l'exécution de la fonction JavaScript `auLancement()` après le chargement de la page HTML. Obligatoire dans ce cas, sinon `auLancement()` ne s'exécute jamais. - `let trs = table.getElementsByTagName("tr");` renvoie un tableau (`HTMLCollection` plus exactement) de tous les éléments `<tr>` de `<table>`. On traite tous les éléments de `trs` avec la première boucle `for`. - `let tds = tr.getElementsByTagName("td");` renvoie un tableau de tous les éléments `<td>` pour chaque `tr`. On traite tous les éléments de `tds` avec la seconde boucle `for`. - `alert(this.id);` : `this` fait référence à `td.onclick` et correspond donc à la case cliquée. - `<input type="hidden" .../>` permet de transmettre des données au serveur. Le serveur récupère la donnée contenu dans l'attribut `value` à l'aide du nom du `input` (attribut `name="case_cliquee"`). - `document.getElementById('hidden').value = this.id;` place le contenu de l'attribut `id` de la case cliquée dans l'attribut `value` du `input` d'attribut `id="hidden"`.