TD11 - JavaScipt : DOM, Intro, évènements

Objectif

  • Dans ce TD, nous allons nous pencher sur la programmation côté client, où le code est exécuté sur la machine du client.

  • Contrairement aux pages HTML générées par la programmation côté serveur, le code source est visible lorsqu’on fait affichage code source dans le navigateur.

Rappel HTML

Exercice 11.1 HTML - Rappel

  1. Aujourd’hui, nous travaillons dans le dossier td11. Copiez votre fichier connexion_base.php dans ce dossier td10.

  2. Créez un nouveau fichier avec le nom intro-js.html, et mettez le code suivant :

<!DOCTYPE html>
<html lang="fr">

    <head>
        <meta charset="utf-8" />
        <title>
            CSWD - TD 11 Javascript
         </title>
    </head> 

    <body>
        <h1>Conception de sites web dynamqiues</h1>
        <h2>Rappel HTML et CSS</h2>
    </body>
    
</html> 
  1. Afficher votre page HTML5 dans votre navigateur, de préférence Mozilla Firefox ou Chrome.

  2. Après le titre <h2>, ajoutez une balise paragraphe <p> avec le texte “L’objectif de ce TD est de :”

  3. Après ce paragraphe, ajoutez une liste non-triée <ul>, avec cinq éléments de liste avec le texte suivant.

  • Un rappel HTML5 et CSS.
  • Comprendre le DOM (Document Object Model).
  • Introduction à JavaScript.-
  • Lier le JavaScript à vos pages HTML5 en - ant le DOM.
  • Programmation évènementielle avec JavaScript.

Exercice 11.2 DOM : Le Document Object Model

Le DOM est une interface de programmation (API) créé par le consortium W3C. Avec le DOM, un document HTML5, et plus précisément les balises, peuvent être représentées sous la forme d’un arbre, et ceci permet à des scripts d’examiner et de modifier le contenu du navigateur web.

  1. Complétez l’arbre DOM de votre page web intro-js.html (sur une feuille de papier avec un stylo). Vous pouvez raccourcir le contenu des feuilles (avec … p.ex.).

  1. Vérifiez votre solution en ouvrant les outils de développement web de votre navigateur. Vous voyez que les éléments y sont bien représentés sous forme d’un arbre (horizontal ici ).

  2. Toujours avec les outils de développement, supprimez un élément de liste <li> (clique droit sur la balise, et sélectionner le menu Supprimer le noeud).

  3. Toujours avec les outils de développement, supprimez la liste <ul>. Avez-vous vu que toute la branche de l’arbre disparaît ?

  4. Recharger la page dans votre navigateur (avec l’icône “recharger” ou en utilisant le raccourci clavier CTRL-R ou CMD-R). La liste réapparait, parce que les modifications n’ont été fait que ans le navigateur, sans bien sûr modifier le fichier intro-js.html.

Rappel CSS

Exercice 11.3 Feuille de style CSS

  1. En utilisant VSCode (ou votre explorateur de fichier), dans votre dossier td11, créez un sous-dossier css et dans ce dossier, un fichier style.css. Votre **arborescence de fichiers} sera donc :
    espaces/
    └── www/
        └── cswd/
            └── td1/
                └── ...
            └── td2/
                └── ...
            └── td11/
                └── css/
                    └── style.css
                └── intro-js.html
  1. Dans votre fichier style.css, ajoutez le texte suivant :
h1 
{ 
    color: rgb(0,0,0);  
    background-color: rgb(221,221,221);    
} 
Note

Rappelez-vous qu’un fichier CSS contient un ensemble de règles, et les règles ont la syntaxe suivante :

sélecteur 
{
    propriété : valeur;
    propriété : valeur;
    ...
}
  1. Pour utiliser une feuille de style stockée dans le fichier css/style.css, il faut ajouter la ligne suivante dans l’en-tête de la page intro-js.html (partie ).
<link href="css/style.css" rel="stylesheet" type="text/css">

Notez que dans votre fichier CSS, la règle utilise un sélecteur simple pour la balise h1 : les propriétés dans le bloc de règles s’appliquent à toutes les balises du sélecteur. Si vous voulez appliquez les règles également aux titres h2, ajoutez le sélecteur en transformant le sélecteur en h1, h2

  1. Avec les outils de développement Web de votre navigateur Chrome ou pour Firefox, modifiez les couleurs et les couleurs de fond de vos titres <h1> <h2>.

  2. Dans votre fichier intro-js.html, choisissez un élément de votre liste et ajoutez un attribut id avec la valeur "important" comme suit :

<li id="important">

Dans votre fichier CSS, ajoutez un sélecteur pour cet identifiant (en utilisant le préfix #), et appliquez une règle pour mettre cet élément de liste avec une couleur de fond grise.

Note

Rappelez-vous qu’il existe aussi les sélecteurs pour les classes (en utilisant le préfix .), et ce sélecteur vise attribut class des balises HTML. La différence est qu’un identifiant n’apparait qu’une seule fois dans le page HTML, tandis que les classes peuvent s’appliquer à plusieurs balises …

JavaScript : Introduction

Exercice 11.4 Hello JavaScript

  1. Dans votre dossier td11, dans votre fichier intro-js.html, avant la fermeture de </body>, créez une balise script qui appelle la fonction JavaScript alert permettant d’afficher un message d’information dans une boîte de dialogue.
<script type="text/javascript">

alert("Bonjour à tous");

</script>
  1. Rechargez votre page dans le navigateur.

  2. Provoquez un message d’erreur en écrivant alert d’une façon erronée, avec deux ‘l’, par exemple.

  3. Testez.

  4. Ouvrez vos outils de développement web (p.ex. sous Chrome : menu “afficher” - “options pour les développeurs” - “console javascript”, et regardez le message d’erreur dans cette console de développement. Corrigez, et testez à nouveau.

  5. Dans votre balise script, ajoutez l’instruction suivante, et testez en rechargeant votre page, et en regardant la sortie dans votre console de développement :

console.log("Message dans la console");
Important

Il y a deux façons d’ajouter du code JavaScript dans une page web :

  • Soit vous ajoutez le code JavaScript directement à l’intérieur de l’élément script comme vu dans cet exercice.

  • Soit vous liez un fichier externe depuis la page HTML dans lequel sont placées les instructions JavaScript. Ceci permet de bien séparer la partie JavaScript de la partie HTML. Nous allons voir ceci dans le prochain exercice.

Exercice 11.5 Fichier JavaScript externe

  1. A partir de maintenant, nous allons travailler avec un fichier externe qui regroupe toutes les instructions JavaScript. Créez un fichier externe intro.js dans votre dossier js. Voici l’arborescence :
espaces/
└── www/
    └── cswd/
        └── td1/
            └── ...
        └── td2/
            └── ...
        └── td11/
            └── css/
                └── style.css
            └── js/
                └── intro.js
            └── intro-js.html
  1. Dans votre fichier intro.js, ajoutez un message de log comme suit :
console.log("Exécution fichier intro.js");
  1. Pour lier le fichier intro.js du dossier js, il suffit d’ajouter la ligne suivante dans votre fichier intro-js.html. Pour l’instant, **mettez cette ligne avant la fermeture de </body> :
<script type="text/javascript" src="js/intro.js"></script>
  1. Tester si vous voyez le message dans votre console de développement.

JavaScript : Programmation de base

Exercice 11.6 Déclarations et affectations de variables

En JavaScript, les trois façons de déclarer des variables et constantes sont let, var et const. L’instruction let a une portée plus strict. Dans ce cours, nous allons préférer l’utilisation de let.

  1. Tapez le code suivant dans votre fichier `intro.js :
let i; // Déclaration d'une variable
i = 0; // Affectation

let s = "text"; // Déclaration et affectation d'une variable en une fois
  1. Compléter ce code en vous affichant le contenu de ces variables et constantes avec plusieurs instructions console.log(...);, par exemple
console.log("i = ", i);
Note

JavaScript est un langage de script à typage dynamique, c’est à dire que l’interpréteur attribue aux variables un type lors de l’exécution en fonction de la valeur actuelle. Dans l’exercice précédent, nous avons déclaré des variables de deux différents types : la variable i est de type number, et la variable s est de type string (chaîne de caractères). Pour ce dernier type, pour associer une valeur, il faut la mettre entre guillemets.

Exercice 11.7 Structures de contrôle : Alternatives

Affectez la variable i à une valeur de votre choix. Expérimentez l’alternative if suivant pour différentes valeur de i :

if (i<0)
{
    console.log("i est négatif");
}
else if (i>0)
{
    console.log("i est positif");
}
else      
{
    console.log("i est 0");
}
Note

Un bloc d’instruction est délimité par des accolades, et il permet d’exécuter plusieurs instructions conditionnellement. Dans l’exemple de cet exercice, il n’y a qu’une seule instruction par bloc d’instruction – dans ce cas là, les accolades sont optionnelles et peuvent aussi être omises. Nous les avons gardées ici pour de raisons de clarté.

Exercice 11.8 Structures de contrôle : Boucles

  1. Testez l’exécution de la boucle suivant :
for (let i=0; i<10; i++)
{
    console.log(i);
}

Exercice 11.8 Structures de contrôle : Fonctions

Une fonction est une routine de programmation qu’on déclare une fois, afin de pouvoir appeler dès qu’on en a besoin. La déclaration d’une fonction peut se faire de différentes façons en JavaScript (fonctions anonymes, etc.). La déclaration classique d’une fonction est :

function maFonction()
{
    console.log("Dans la fonction nom.");
}

Un appel de fonction se fait comme suit :

maFonction();
  1. Dans le corps de votre boucle for, après l’affichage de i dans la console, appelez la fonction maFonction(). Vérifiez si l’affichage dans la console correspond à ce que vous attendiez.

  2. Au sens strict, l’exemple précédent portait plutôt sur une procédure, car il n’y avait ni de paramètres, ni de renvoi de valeur. Une fonction au sens strict prend des paramètres, et renvoie un résultat. Considérez la fonction suivante qui prend un paramètre, et qui renvoie le carré de ce paramètre :

function carre(x)
{
    let y = x * x;
    return y;
}
  1. Testez votre fonction, en l’appelant comme suit. Comprenez vous le résultat ?
let resultat = carre(6);
console.log(resultat);
  1. Testez votre fonction, par exemple dans la boucle, en affichant le résultat de la fonction pour chaque valeur de i.

JavaScript : Faire le lien avec le DOM

Par la suite, nous allons faire le lien de votre page web intro-js.html et de JavaScript via l’accès et la manipulation du DOM (Document Object Model). Pour cela, nous allons d’abord voir comment accéder aux balises, et ensuite comment manipuler leurs contenus, leurs attributs, et leurs styles.

Exercice 11.9 Javascript : accéder aux balises du DOM

Afin de récupérer une balise afin de le manipuler en JavaScript, il existe plusieurs façons. La façon la plus classique est d’accéder via l’identifiant, ce que nous allons voir dans cet exercice.

  1. A la suite de votre page HTML5 (après votre liste <ul>), ajoutez le code suivant comprenant un titre, un paragraphe, ainsi qu’une balise <strong> ayant un attribut identifiant nomAffichage :
<h2>Manipuler le DOM avec JavaScript</h2>
<h3>Introduction</h3>
<p>Bonjour, <strong id="nomAffichage">visiteur</strong> !</p>
  1. Testez.

  2. Nous allons maintenant accéder à la balise avec l’attribut id="nomAffichage" avec l’instruction document.getElementById(...). Donc, ajoutez l’instruction suivante dans votre script JavaScript.

let nomAffichage = document.getElementById("nomAffichage");

Pour l’instant, il n’y a pas d’effet visible, nous avons simplement déclaré une variable qui contient toute la balise avec l’identifiant nomAffichage, incluant son contenu, ses attributs, etc. Nous allons nous servir dans le prochain exercice.

Note

Pour la lisibilité, si nous avons besoin d’accéder à une balise d’un identifiant, nous essayons de systématiquement déclarer une variable portant le même nom que l’identifiant (ici, c’est donc la variable nomAffichage pour l’identifiant nomAffichage …).

Exercice 11.10 Javascript : modifier contenu des balises

Vous pouvez maintenant accéder au contenu d’une balise avec innerHTML. Voici un exemple qui affiche le contenu d’une balise dans la console. Ajoutez l’instruction suivante dans votre script JavaScript :

console.log("Nom : ", nomAffichage.innerHTML);

// ou alors, si vous n'avez pas récupéré l'objet dans une variable

console.log("Nom : ", document.getElementById("nomAffichage").innerHTML);

Vous avez également la possibilité de changer le contenu d’une balise, comme suit :

nomAffichage.innerHTML = "Max";

// ou alors, si vous n'avez pas récupéré l'objet dans une variable

document.getElementById('nomAffichage').innerHTML = "Max";

JavaScript : Programmation évenementielle

Exercice 11.11 Evènement click sur une balise HTML5

Dans cet exercice, nous souhaitons réagir lorsque l’utilisateur clique sur une balise HTML5.

  1. A la suite de votre page HTML5, ajoutez le code suivant comprenant un titre et un bouton ayant un attribut identifiant changerNomEnMauriceBouton, comme suit.
<h3>Un premier évènement (modifier le contenu d'une balise)</h3>

<button id="changerNomEnMauriceBouton">Changer le nom en "Maurice"</button>
  1. Testez et cliquez sur le bouton, ce qui n’a pas d’effet pour l’instant.

  2. Nous allons maintenant ajouter un écouteur (listener) à ce bouton, et nous spécifions le nom de la fonction à appeler. Cette fonction, ici modiferNom, s’appelle une fonction de Callback . Dans un premier temps, votre fonction affichera une fenêtre de message afin de vérifier le fonctionnement. Testez le code suivant :

let changerNomEnMauriceBouton = document.getElementById("changerNomEnMauriceBouton");
changerNomEnMauriceBouton.addEventListener("click", modifierNom);

function modifierNom()
{
    alert("Dans modifierNom");
}
  1. Modifiez la fonction modifierNom() afin de modifier la balise avec l’identifiant nomAffichage en “Maurice”. Testez !
Important

Il est possible aussi d’ajouter simplement un attribut onclick="modifierNom()" à la balise du bouton - au lieu de passer par ajouter le EventListener en JavaScript. Bien que cela apparaît plus simple, il est généralement déconseille de le faire de cette façon, car cela “cache” les instructions JavaScript dans le code HTML.

Important

Notez qu’en plus de l’évènement click, vous disposez également d’autres évènements, comme par exemple mouseover ou mouseout. Notez également que les évènements ne sont pas limités à être associés aux balises de type bouton : vous pouvez très bien en associer à des images, des paragraphes, etc. Nous allons voir cela dans les prochains exercices.

Exercice 11.12 JavaScript : accéder aux attributs des balises (1)

  1. Dans la suite de votre fichier HTML5, ajoutez une balise input avec une étiquette permettant à l’utilisateur de saisir son nom, en mettant par défaut le nom “Matthieu” dans l’attribut value, suivi d’un bouton comme suit :
<h3>Un deuxième évènement (modifier un attribut d'une balise)</h3>
<label for="nom">Nom:</label>
<input type="text" value="Matthieu" name="nom" id="nom" />
<button id="validerNomBouton">Valider</button>
  1. Dans les exercices précédents, nous avons vu comment accéder au contenu d’une balise avec innerHTML, et maintenant, nous allons voir comment accéder aux attributs d’une balise via JavaScript. Par exemple, pour accéder à l’attribut value de la balise input ayant l’attribut identifiant nom, vous pouvez faire :
let nom = document.getElementById("nom");
console.log("Nom : ",nom.value);

// pour modifier
nom.value = "Homer";
  1. Testez.

  2. Maintenant c’est à vous de montrer que vous avez compris : liez un évènement au clic sur le bouton “Valider” qui récupère la valeur du champs texte, et qui modifie la balise avec l’identifiant nomAffichage ! Pour cela, il faut associer un évènement au clic du bouton qui appelle une fonction, par exemple validerNom, et déclarer cette fonction.

Exercice 11.13 JavaScript : accéder aux styles d’une balise

Vous pouvez également consulter et modifier les styles CSS d’une balise via JavaScript.

  1. Dans la suite de votre fichier HTML5, ajoutez un nouveau titre, ainsi que les balises suivantes :
<h3>Un quatrième évènement (modifier le style d'une balise)</h3>
<p>Paragraphe 1</p>
<button id="lireLaSuiteBouton">Lire la suite ...</button>
<div id="suite" style="display: none">
    <p>Paragraphe 2</p>
    <p>Paragraphe 3</p>
</div>
  1. Remplacez les paragraphes 1, 2, et 3 avec les 3 paragraphes du faux texte Lorem Ipsum (version populaire).

  2. Testez. Avez-vous compris pourquoi les paragraphes 2 et 3 ne sont pas affichés ?

  3. Voici une fonction :

function lireLaSuite()
{
    let suite = document.getElementById("suite");
    suite.style.display = "block"; // ou "block" pour le faire apparaître
}
  1. Associez un évènement à votre balise button qui appelle la fonction lireLaSuite au clic de la souris.
Note

Les propriétés CSS qui contiennent le symbole “tiré” (-), comme par exemple background-color, doivent être adressés via un mot en tout attaché et un majuscule. Ici, ce serait par exemple

suite.style.backgroundColor = "\#CCCCCC";

Exercices optionnels : cartes + images

Exercice 11.14 JavaScript : utilisations des cartes interactives avec Leaflet

Dans cette exercice, nous allons intégrer une carte interactive dans une page web. Pour cela, nous allons utiliser la bibliothèque OpenSource Leaflet https://leafletjs.com/.

  1. Créez un nouveau fichier carte.php avec les balises HTML habituels.
Important

J’avais oublié de vous indiquer qu’il faut bien sur inclure le fichier css et JavaScript de Leaflet. Donc, avant la fermeture de votre balise </head>, insérez les lignes suivantes :

<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=" crossorigin=""/>

<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js" integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin=""></script>
  1. Créez un titre <h2> avec le texte “Voici la carte :”.

  2. Insérez la balise suivante

<div id="map" style="width: 600px; height: 400px;"></div>
  1. Avant la fermeture de la balise </body>, insérez le script JavaScript suivant :
<script>
const map = L.map('map').setView([51.505, -0.09], 13);

const tiles = L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
    maxZoom: 19,
    attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
}).addTo(map);

const marker1 = L.marker([51.5, -0.09],{draggable:'false'}).addTo(map).bindPopup('<b>Hello CSWD !</b><br />Je suis un popup, je peux contenir des informations.').openPopup();
</script>
  1. Vous pouvez faire en sorte que votre marqueur marker1 puisse être bougé par l’utilisateur. Pour cela, mettez l’attribut draggable à la valeur true.

  2. Pour suivre la position du marqueur, vous pouvez introduire deux balises HTML, avec les identifiants latitude et longitude comme suit :

Latitude : <input type="text" name="latitude1" id="latitude1"/>
Longitude : <input type="text" name="longitude1" id="longitude1"/>

Afin de mettre à jour ces balises, vous pouvez ajouter l’instruction JavaScript suivant :

marker1.on('drag', function (e) {
            document.getElementById('latitude1').value = marker1.getLatLng().lat;
            document.getElementById('longitude1').value = marker1.getLatLng().lng;
      });

Ceci peut vous être utile pour laisser déterminer des positions sur une carte par les utilisateur interactivement, par exemple dans un formulaire, pour insérer ces informations dans une table d’une base de données …

Exercice 11.15 JavaScript : accéder aux attributs des balises (2)

Dans cet exercice, nous allons modifier une image au survol de la souris.

  1. Pour cela, prenez deux images de votre choix avec une même définition (p.ex. 256x256 pixels), et stockez-les dans un sous-dossier images sous les noms image1.jpg et image2.jpg.

  2. Dans la suite de votre fichier HTML5, ajoutez un nouveau titre, ainsi que la balise pour afficher l’image image1.jpg comme suit :

<h3>Un troisième évènement (modifier un attribut d'une balise)</h3>
<img id="image" src="images/image1.jpg" alt="image" />

Comme vous le savez, dans la balise img, l’attribut src spécifie le nom du fichier de l’image à afficher.

  1. En JavaScript, définissez une fonction modifierEnImage2() qui change l’image en mettant l’image image2.jpgdans cette balise img avec l’identifiant image.

  2. Testez votre fonction.

  3. Associez un évènement à votre balise img qui appelle la fonction modifierEnImage2 au survol de la souris (évènement mouseover).

  4. Pour remettre l’image image1.jpg lorsque votre pointeur de souris n’est plus “au-dessus” de l’image, définissez une fonction modifierEnImage1, et appelez cette fonction lors de l’évènement mouseout de l’image.

Important
  • Cette semaine, les exercices sont à rendre sur moodle jusqu’au lundi, 7 avril prochain, 23h59.