Les TP de JavaScript se déroulent sur ce logiciel appelé « Moodle ».
Vous devez travailler connectés (lien « Connexion » en haut à droite
de la page). Sinon, vous rencontrerez des problèmes d'avancement et
vous risquez d'être comptés absent. En étant connectés vous retrouverez
l'endroit où vous en
étiez à la séance suivante.
Dans ces TP, vous trouverez des explications à lire, des questions à répondre et des exercices plus libres.
Prenez le temps de réfléchir par vous même avant de répondre à une question. Le but n'est pas de trouver la bonne réponse, mais de comprendre et apprendre. Ne vous contentez pas de recopier les réponses de vos voisins.
Ces TP ne sont PAS notés. Les notes affichées par le logiciel ne comptent pas dans votre évaluation.
N'hésitez pas à appeler votre enseignant. Il est là pour vous aider.
Moodle permet à chacun d'évoluer à son propre rythme. Certains avanceront plus ou moins rapidement. Finissez chaque TP avant de passer au suivant. Si vous sautez des questions, vous risquez de ne plus comprendre.
A gauche, en haut de la page vous trouverez un menu qui vous permet d’accéder aux différentes parties de chaque TP.
Ces TP sont prévus pour Firefox sous Linux, pas pour Windows.
Dans les pages suivantes, nos premier pas en JavaScript.
JavaScript est un langage de programmation déjà intégré dans votre navigateur !
Vous n'avez pas besoin d'installer d'autres logiciels... il suffit d'ouvrir la console 😀
Ouvrez la console:
Ctrl + Maj + K sur Firefox
Ctrl + Maj + J sur Chrome
Dans la console tapez: 1+1 suivi d'entrée
Ça y est ! Vous avez écrit du JavaScript ! 😀
Écrivez maintenant dans la console:
alert('Coucou!')
La fonction "alert" affiche une fenêtre popup.
Écrivez maintenant:
console.log('haha')
console.log(...) est comme "print" ou "printf" dans d'autres langages ... très utile pour débugger.
En fait, on peut écrire du code JavaScript plus compliqué directement dans la console. Essayez:
for(let i=0;i<10;i++){console.log(i);}
La première fois que vous faites un copier coller dans la console de Firefox, vous rencontrez le message suivant:
Tapez, à la main, "autoriser le collage"
Le JavaScript vous permet de modifier la page sur laquelle vous vous trouvez.
Comme tous les documents HTML, la page actuelle (que vous lisez) est structurée comme ceci:
<!DOCTYPE html>
<html lang="fr">
<head>...</head>
<???>...</???>
</html>
Vous souvenez-vous du nom de la balise qu'il faut écrire à la place de ???
(répondez ci-dessous... juste son nom)
(en cas de doute: https://developer.mozilla.org/fr/docs/Learn/HTML/Introduction_to_HTML/Getting_started#anatomie_dun_document_html)
Le CSS permet de changer l'affichage d'une page.
Il y a 3 manières d'ajouter du CSS à une page web:
1. Le lien vers un fichier CSS (c'est le plus propre):
<!DOCTYPE html>2. Le CSS dans une balise <style>:
<html lang="fr">
<head>
<title>My HTML Document</title>
<link rel="stylesheet" href="exemple.css" />
</head>
<body>
...
<!DOCTYPE html>
<html lang="fr">
<head>
<title>My HTML Document</title>
<style>
p {
color: green;
} </style>
</head>
<body>
...
3. L'attribut style
Moins utilisé habituellement, mais très utilisé en JS:
<p style="border: solid;font-size: 20px;">exemple</p>
--
Voici un titre :
<h1>bonjour</h1>
Re-écrivez ce titre HTML pour qu'il soit affiché avec une couleur de fond verte en utilisant l'attribut style
Vous êtes sur la bonne voie. Vous avez écrit :
<h1 style="...">bonjour</h1>
C'est correct. Le problème est dans les "...".
On va donc faire:
document.body.style.backgroundColor='red'
Essayez dans la console !
En utilisant votre éditeur de texte préféré (gedit, atom, vscode, ...), créez le fichier hello.html suivant (quelque-part où il ne sera pas perdu).
<!DOCTYPE html>Ouvrez-le dans votre navigateur avec CTRL+O
<html lang="fr">
<head>
<meta charset="utf-8"/>
<title>Hello World JS</title>
</head>
<body>
<h1 style="color:yellow">Bonjour!</h1>
<p>
<img src="https://moodle.iutv.univ-paris13.fr/img/bjs/tux.png" alt="tux"/>
</p>
<script>
console.log('Coucou');
</script>
</body>
</html>
document.body.style.backgroundColor='red'Rechargez la page.
document.body.style.backgroundColor='green';
puis rechargez la page.
En JavaScript, on veut souvent manipuler ce qui est affiché sur la page.
On a vu qu'on pouvait accéder à <body> avec document.body
Pour accéder au h1 on peut utiliser: document.querySelector('h1')
Avec la ligne:
document.querySelector('h1').style.backgroundColor='blue'
En utilisant la même approche pour modifier style, essayez d'autres propriétés CSS, comme color, font-size (fontSize en JS), border.
Ensuite, au lieu de modifier "style", essayez de modifier "textContent"
Attention:
"style" a des sous-propriétés, comme color, backgroundColor, ... Ce sont les propriétés CSS :
document.querySelector('h1').style.backgroundColor='blue';
document.querySelector('h1').style.color='blue';
Par contre "textContent" prend directement une chaîne de caractères:
document.querySelector('h1').textContent='Abcdef';
Essayez à la fois dans la console et dans le code JavaScript qui se trouve dans les balises <script>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8"/>
<title>Hello World JS</title>
</head>
<body>
<h1 style="color:yellow">Bonjour!</h1>
<p>
<img src="https://moodle.iutv.univ-paris13.fr/img/bjs/tux.png" alt="tux"/>
</p>
<script>
document.querySelector('h1').style.backgroundColor='blue';
document.querySelector('h1').style.color='green';
document.querySelector('h1').style.fontSize='50px';
document.querySelector('h1').style.border='4rem ridge rgba(170,50,220,.6)';
document.querySelector('h1').textContent='Yes!';
</script>
</body>
</html>
Avec la ligne:
document.querySelector('h1').style.backgroundColor='blue'
On a fait plusieurs choses:
1) document.querySelector('h1') : chercher l'élément h1
2) .style. : accéder à son attribut style
3) backgroundColor='blue' : associer la valeur "blue" à la propriété CSS background-color
Dans la même logique, on va essayer de modifier l'image:
<img src="http://moodle.iutv.univ-paris13.fr/img/js/tux.png" alt="tux"/>
Pour l'instant on fait uniquement l'étape 1.
En vous inspirant de l'étape 1, que faut-il écrire pour chercher l'élément img ?
(uniquement l'étape 1)
document.querySelector('img')
Maintenant on veut, en JS, changer son attribut src.
Actuellement l'image est:
<img src="https://moodle.iutv.univ-paris13.fr/img/bjs/tux.png" alt="tux"/>Avec le JS, on veut changer
Écrivez la ligne JS en entier permettant d’accéder à l'image (vu à la question précédente) et de changer src :
Essayez dans la console et dans votre code avant de répondre ici.
<!DOCTYPE html>Ouvrez le dans le navigateur (CTRL+O).
<html lang="fr">
<head>
<meta charset="utf-8"/>
<title>Hello World JS</title>
</head>
<body>
<h1 style="color:yellow">Bonjour!</h1>
<p>
<img src="https://moodle.iutv.univ-paris13.fr/img/bjs/tux.png" alt="tux"/>
</p>
<script>
document.querySelector('h1').addEventListener('click',ma_fonction);
function ma_fonction()
{
document.querySelector('img').src='https://moodle.iutv.univ-paris13.fr/img/bjs/smile.png';
}
</script>
</body>
</html>
document.querySelector('h1').addEventListener('click',ma_fonction);dit au navigateur "Enregistre la fonction ma_fonction sur le h1, pour qu'elle puisse être appelée, plus tard, chaque fois que l'utilisateur clique sur ce h1"
Ensuite, les lignes suivantes définissent la fonction "ma_fonction". Quand cette fonction est appelée, elle change le src de l'image.
function ma_fonction()
{
document.querySelector('img').src='https://moodle.iutv.univ-paris13.fr/img/bjs/smile.png';
}
<!DOCTYPE html>Exemple 2:
<html lang="fr">
<head>
<meta charset="utf-8"/>
<title>Hello World JS</title>
</head>
<body>
<h1 style="color:yellow">Bonjour!</h1>
<p>
<img src="https://moodle.iutv.univ-paris13.fr/img/bjs/tux.png" alt="tux"/>
</p>
<script>
document.querySelector('img').addEventListener('click',ma_fonction);
function ma_fonction()
{
alert('bonjour!');
}
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8"/>
<title>Hello World JS</title>
</head>
<body>
<h1 style="color:yellow">Bonjour!</h1>
<p>
<img src="https://moodle.iutv.univ-paris13.fr/img/bjs/tux.png" alt="tux"/>
</p>
<script>
document.querySelector('h1').addEventListener('click',ma_fonction1);
document.querySelector('img').addEventListener('click',ma_fonction2);
function ma_fonction1()
{
document.querySelector('img').src='https://moodle.iutv.univ-paris13.fr/img/bjs/smile.png';
}
function ma_fonction2()
{
alert('Aha!');
}
</script>
</body>
</html>
let a;
a=123;
a=1.5;
a='bonjour';
let a=123;
Contrairement au Python, en JavaScript le nombre d'espaces n'est pas important (par exemple pour l'indentation). On utilise { et } pour délimiter un block.
Python:
if b > a:
print("Ceci est affiché seulement si b > a")
print("Ceci est toujours affiché")
JavaScript:
if ( b > a ) {
console.log('Ceci est affiché seulement si b > a');
console.log('Ceci est aussi affiché seulement si b > a');
}
console.log('Ceci est toujours affiché');
Le Python se passe des accolades, le block est indiqué par l'indentation (espaces).
Le JavaScript utilise les accolades pour indiquer le début et la fin du block et ignore l'indentation (espaces).
Écrivez, en une seule ligne, en utilisant des accolades, du JavaScript affichant sur la console "trop jeune" seulement si la variable age est inférieure à 18.
Vous avez inversé la condition !
Pour créer des boucles simples en JavaScript on peut utiliser "for".
"for" s'écrit comme ceci:
for(initialisation; condition pour continuer; code fin de chaque itération) {
...
}
Cette boucle est équivalente à :
initialisation
while(condition pour continuer){
...
code fin de chaque itération
}
Très souvent, la boucle "for" est utilisée pour parcourir des nombres.
for(let i=0; i < 10 ; i++) {
...
}
ceci est équivalent à:
let i=0;
while(i<10) {
...
i++;
}
Quand vous avez ces 3 parties (initialisation, condition, fin), c'est plus propre (plus lisible) d'utiliser une boucle for qu'une boucle while.
En une seule ligne, écrivez une boucle for sur i qui affiche dans la console tous les nombres de 0 à 5 (donc 0 1 2 3 4 5).
(Essayez dans la console avant de répondre)
Commentaires
En JS, il y a deux types de commentaires:
Par exemple:
Ceci n'est pas en commentaire // Tout le reste de la ligne est en commentaire
// Toute cette ligne est en commentaire
Pas en commentaire /* en commentaire */ pas en commentaire
Quelles parties sont en commentaire ?
abc // def
hij /* klm */ nop /* qrs */ tuv // wxy
En JS, les chaînes de caractères utilisent des guillemets simples ' ou doubles ":
let s='abc';
let t="abc";
Pour coller deux chaînes ensemble (concaténation), on utilise le "+" :
'abc'+'def' donne 'abcdef'
On peut concaténer un nombre et une chaîne:
123+'em' donne '123em'
Supposons qu'une variable i contienne un nombre (par exemple: let i = 500 ou let i= 456).
Que faut-il écrire pour obtenir une chaîne constitué du nombre dans i suivi par 'px' ?
En JS, on manipule beaucoup les fonctions.
En JavaScript on déclare une fonction appelée "ceci_est_une_fonction" comme ceci:
// Exemple de fonction:
function ceci_est_une_fonction()
{
....
}
Déclarez, en une seule ligne, une fonction appelée "bonjour" et qui affiche "hello" dans la console.
Une fonction peut prendre des paramètres. Dans cet exemple, la fonction ceci_est_une_fonction prend 3 paramètres a, b et c:
function ceci_est_une_fonction(a,b,c)
{
....
}
Déclarez, en une seule ligne, une fonction appelée "affiche", qui prend un seul paramètre x, et qui affiche x dans la console.
Par exemple affiche('coucou') affichera "coucou" dans la console.
Attention: probablement nouveau pour vous ... et très utilisé ! Important.
En JS, une fonction est une valeur qui peut être, par exemple, mise dans une variable.
function ceci_est_une_fonction(x)
{
console.log(x);
}
// On met une référence de la fonction dans la variable a:
let a=ceci_est_une_fonction;
// On peut donc appeler "a" comme une fonction:
a('hello');
Ce sont les parenthèses qui distinguent l'appel d'une fonction de sa "valeur" (en fait une référence vers la fonction):
Exemple:
function affiche(x) { console.log(x); }
function ma_fonction()
{
document.body.style.color='green';
}
Rappel: Ce sont les parenthèses qui distinguent l'appel d'une fonction de sa "valeur" (en fait une référence vers la fonction):
function exemple()Que vaut a ?
{
return 123;
}
let a=exemple();
Rappel: Ce sont les parenthèses qui distinguent l'appel d'une fonction de sa "valeur" (en fait une référence vers la fonction):
function exemple()Que vaut a ?
{
return 123;
}
let a=exemple;
Comme une fonction est une "valeur", on peut aussi la passer en paramètre à une autre fonction.
Ça semble tiré par les cheveux, mais c'est très utilisé en JS ... et on l'a même déjà fait ensemble ! 😲
Souvenez-vous:
document.querySelector('h1').addEventListener('click',ma_fonction);On passe "ma_fonction" en 2e paramètre de la fonction "addEventListener".
function ma_fonction()
{
document.querySelector('img').src='https://moodle.iutv.univ-paris13.fr/img/bjs/smile.png';
}
Ceci demande au navigateur: "Enregistre la fonction ma_fonction sur le h1, pour qu'elle puisse être appelée, plus tard, quand l'utilisateur clique sur ce h1"
Voyons un autre exemple. Que fait le code suivant ?
function f()
{
console.log('Bonjour');
}
function g(x)
{
x();
}
g(f);
Le HTML est un format texte, mais il est interprété par le navigateur comme un arbre.
Chaque noeud de l'arbre correspond à une balise. Dans le navigateur, chaque noeud sera un objet qu'on pourra manipuler en JS.
L'ordre des balises compte.
Le texte contenu dans chaque balise est représenté par un noeud « Text ». En général, on ne montrera pas sur les schémas les noeuds « Text ».
C'est très important d'avoir toujours en tête la correspondance HTML <=> arbre
<body>
<p>
Un exemple de page en html.<br/>
<img src="photo.jpg" alt="photo"/>
</p>
<ul>
<li>pomme</li>
<li>fraise</li>
</ul>
</body>
Remarque: dans ces schémas, on ne tient pas compte du texte.
<!DOCTYPE html>(<!DOCTYPE> n'est pas dans l'arbre)
<html>
<head>
<meta charset="utf-8"/>
<title>Exemple</title>
</head>
<body>
<h1>Bonjour!</h1>
</body>
</html>
Écrivez en une seule ligne un exemple de HTML correspondant à l'arbre suivant.
(vous pouvez inventer le contenu que vous voulez)
Écrivez en une seule ligne un exemple de HTML correspondant à l'arbre suivant.
(vous pouvez inventer le contenu que vous voulez)
Le navigateur reçoit et analyse le HTML. En mémoire, il crée des objets (au sens Programmation Orientée Objet) correspondant à chaque balise. Ces objets sont organisés dans un arbre.
Dans cet exemple « i » est l'objet DOM correspondant à une image.
«
i » est un objet avec des propriétés. On y accède comme ceci i.nomProprieté
Certaines propriétés correspondent aux
attributs HTML (style, src...):
on peut lire et parfois modifier ces propriétés
En JavaScript, on utilise souvent les « sélecteurs ».
Vous avez appris à utiliser les sélecteurs en CSS. Les sélecteurs permettent de désigner depuis le CSS des éléments HTML (des éléments dans l'arbre DOM). On va aussi les utiliser en JavaScript pour designer les éléments du DOM.
Quel(s) élément(s) correspondent au sélecteur suivant?
#popup
Quel(s) élément(s) correspondent au sélecteur suivant?
#p
Quel(s) élément(s) correspondent au sélecteur suivant?
img
Quel(s) élément(s) correspondent au sélecteur suivant?
.img
Presque tous les programme JS que l'on va écrire réagiront à des événements.
Le navigateur gère de nombreux types d'événements. En voici quelques-uns:
Créez le fichier bouton.html suivant et ouvrez le dans votre navigateur (Ctrl+O)
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8"/>
<title>Bouton</title>
</head>
<body>
<input type="button" value="Appuyer"/>
<p>
Bonjour!
</p>
<script>
let bouton=document.querySelector('...');
bouton.addEventListener('click',fonction_a_appeler);
function fonction_a_appeler()
{
let paragraphe=document.querySelector('...');
paragraphe.style.color='...';
}
</script>
</body>
</html>
En vous inspirant de ce que l'on a fait au début, complétez ce fichier.
Quand l'utilisateur clique sur le bouton, le paragraphe s'affiche en rouge.
Voici la correction:
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8"/>
<title>Bouton</title>
</head>
<body>
<input type="button" value="Appuyer"/>
<p>
Bonjour!
</p>
<script>
let bouton=document.querySelector('input');
bouton.addEventListener('click',fonction_a_appeler);
function fonction_a_appeler()
{
let paragraphe=document.querySelector('p');
paragraphe.style.color='red';
}
</script>
</body>
</html>
b.addEventListener('click',fonction_a_appeler);
Dans ce cours, addEventListener sera presque toujours appelée au chargement de la page.
"fonction_a_appeler" n'est pas appelée au chargement de la page. Elle n'est appelée que plus tard, lorsque l'utilisateur
clique avec la souris. On appelle cette fonction un « gestionnaire
d'événement » (« event listener » en anglais).
addEventListener ne fait que enregistrer la fonction "fonction_a_appeler" sur le bouton.
let bouton=document.querySelector('input');
bouton.addEventListener('click',fonction_a_appeler);
function fonction_a_appeler()
{
let paragraphe=document.querySelector('p');
paragraphe.style.color="red";
}
L'utilisateur clique 5 fois sur le bouton.
let bouton=document.querySelector('input');
bouton.addEventListener('click',fonction_a_appeler);
function fonction_a_appeler()
{
let paragraphe=document.querySelector('p');
paragraphe.style.color="red";
}
Créez le fichier pos-click.html suivant:
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8"/>
<title>Pos click</title>
</head>
<body>
<p>
Bonjour!
</p>
<script>
document.addEventListener('click',fonction_a_appeler);
function fonction_a_appeler()
{
console.log('coucou');
}
</script>
</body>
</html>
Ouvrez-le dans le navigateur (Ctrl+O) et ouvrez la console (Ctrl+Maj+K).
Cliquez plusieurs fois sur la page et regardez la console.
Attention: au lieu de répéter le même message plusieurs fois, la console affiche le nombre de répétitions:
Rappel:
Pour qu'une fonction f soit appelée lorsqu'un utilisateur clique sur un élément el on utilise addEventListener:
el.addEventListener('click', f)
Ceci attache la fonction "f" à la cible "el"
Dans le programme de la page précédente on a écrit:
document.addEventListener('click',fonction_a_appeler);
function fonction_a_appeler()
{
console.log('coucou');
}
Quelle cible a-ton spécifié ?
document.addEventListener("click",fonction_a_appeler);
function fonction_a_appeler()
{
console.log('coucou');
}
Quand l'utilisateur clique, qui appelle fonction_a_appeler ?
document.addEventListener('click',fonction_a_appeler);
function fonction_a_appeler()
{
console.log('coucou');
}
Quand l'utilisateur clique, le navigateur appelle fonction_a_appeler. Le navigateur fournit un paramètre qui contient des informations sur l'événement. Par exemple:
document.addEventListener('click',fonction_a_appeler);Cliquez sur la page et regardez la console.
function fonction_a_appeler(event)
{
console.log('coucou',event.pageX,event.pageY);
}
On voudrait, à chaque click, afficher la position X de la souris dans le paragraphe (à la place de "Bonjour !").
Modifiez le programme actuel:
document.addEventListener('click',fonction_a_appeler);
function fonction_a_appeler(event)
{
console.log('coucou',event.pageX,event.pageY);
}
Utilisez textContent pour modifier le texte affiché dans le paragraphe.
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8"/>
<title>Pos click</title>
</head>
<body>
<p>
Bonjour!
</p>
<script>
document.addEventListener('click',fonction_a_appeler);
function fonction_a_appeler(event)
{
console.log('coucou',event.pageX,event.pageY);
let paragraphe=document.querySelector('p');
paragraphe.textContent=event.pageX;
}
</script>
</body>
</html>
<p>
La souris se trouve à la position
x=<span id="affiche-x">?</span>,
y=<span id="affiche-y">?</span>
</p>
Révision :quel est le sélecteur qui permet de désigner <span id="affiche-y"> ?
Non, voici un rappel:
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8"/>
<title>Pos click</title>
</head>
<body>
<p>
La souris se trouve à la position
x=<span id="affiche-x">?</span>,
y=<span id="affiche-y">?</span>
</p>
<script>
document.addEventListener('click',fonction_a_appeler);
function fonction_a_appeler(event)
{
console.log('coucou',event.pageX,event.pageY);
...
}
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8"/>
<title>Pos click</title>
</head>
<body>
<p>
La souris se trouve à la position
x=<span id="affiche-x">?</span>,
y=<span id="affiche-y">?</span>
</p>
<script>
document.addEventListener('click',fonction_a_appeler);
function fonction_a_appeler(event)
{
console.log('coucou',event.pageX,event.pageY);
let ax=document.querySelector('#affiche-x');
let ay=document.querySelector('#affiche-y');
ax.textContent=event.pageX;
ay.textContent=event.pageY;
}
</script>
</body>
</html>
Dans votre programme précédent, remplacez successivement "click" par par chacun des types d'événements suivants:
Regardez bien à quel moment se met à jour l'affichage lorsque vous agissez sur le bouton.
Pour quel type d'événement est-ce qu'aucune action sur le bouton n'est nécessaire ?
Le JavaScript est un langage de programmation. Dans ce cours, le JS s’exécute uniquement dans le navigateur.
Un exemple simple:
Vous cliquez sur un lien pour visiter une page.
Quelles affirmations sont vraies ?
Ceci est du DOM :
<div><p>Hello</p></div>
Ce code est du HTML, pas du DOM:
<div><p>Hello</p></div>
Le DOM est un arbre, pas du texte.
Ce code modifie le HTML:
document.querySelector('p').textContent='Coucou';
Le JS modifie le DOM, pas le HTML. En effet le navigateur ne conserve pas le HTML après avoir construit l'arbre DOM.
Quand on modifie le DOM l'affichage peut changer.
Pour changer l'affichage, le JS modifie le DOM. Le navigateur met automatiquement à jour l'affichage.
Exemple HTML
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8"/>
<title>Exemple</title>
</head>
<body>
<h1>Cliquez-moi!</h1>
<p>Bonjour!</p>
<script>
let abc=document.querySelector('h1');
abc.addEventListener('click',fonction_a_appeler);
function fonction_a_appeler()
{
let xyz=document.querySelector('p');
xyz.style.color='green';
}
</script>
</body>
</html>
La plupart des programmes JS qu'on écrit ici font les opérations suivantes:
Les programmes JS vont réagir à des événements (click souris, touche clavier, mouvement souris ...)
Ces événements surviennent toujours sur un élément DOM (h1, p, ....) précis.
Pour réagir, on enregistre notre fonction sur cet élément DOM:
Si on veut réagir à un click sur cet h1, il faut enregistrer notre fonction sur cet h1.
Exemple :
abc.addEventListener('click',fonction_a_appeler);
on enregistre la fonction fonction_a_appeler sur abc (abc est la variable qui fait référence au h1).
Cette opération (enregistrer la fonction) se fait, en général, au chargement de la page.
Plus
tard, quand le navigateur s’aperçoit d'un événement sur un élément il
regarde si une fonction (gestionnaires d'événements) est enregistrée sur
cet élément. Si c'est le cas, le navigateur appelle la fonction.
Exemple:
L'utilisateur
clique sur h1. Le navigateur voit que fonction_a_appeler est
enregistrée sur ce h1. Il appelle cette fonction.
.
Gestionnaires d'événements
1: <!DOCTYPE html>
2: <html lang="fr">
3: <head>
4: <meta charset="utf-8"/>
5: <title>Exemple</title>
6: </head>
7: <body>
8: <h1>Cliquez-moi!</h1>
9: <p>Bonjour!</p>
10: <script>
11: let abc=document.querySelector('h1');
12: abc.addEventListener('click',fonction_a_appeler);
13: function fonction_a_appeler()
14: {
15: let xyz=document.querySelector('p');
16: xyz.style.color='green';
17: }
18: </script>
19: </body>
20: </html>
Au chargement de la page, le navigateur reçoit le HTML et crée le DOM au fur et à mesure.
Si le navigateur voit une balise ouvrante, il la crée dans le DOM. Si cette balise est <script> alors il exécute le JS immédiatement.
Les lignes 11 et 12 sont donc exécutées dès le chargement de la page.
Les lignes 13,14,15,16,17 forment juste une déclaration de fonction. Cette fonction n'est pas exécutée au chargement de la page.
Remarquez que la ligne 12 enregistre la fonction "fonction_a_appeler" sur abc (h1).
A la ligne 18, notre script a fini de s’exécuter. On est toujours au chargement de la page.
Chaque fois que l'utilisateur clique sur le h1, "fonction_a_appeler" est appelée. Ceci arrive bien après le chargement de la page.
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8"/>
<title>Exemple</title>
</head>
<body>
<h1>Cliquez-moi!</h1>
<p>Bonjour!</p>
<script>
A: function bleu()
A: {
A: document.querySelector('h1').style='color:blue';
A: }
B: document.querySelector('h1').style='color:green';
</script>
<h2>Un titre plus petit</h2>
<script>
C: let abc=document.querySelector('h1');
C: abc.addEventListener('click',fonction_a_appeler);
D: function fonction_a_appeler()
D: {
D: let xyz=document.querySelector('p');
D: xyz.style.color='green';
D: }
</script>
E: <p>Tout en bas</p>
</body>
</html>
Quand sont exécutées ou prise en compte ces parties ?
A
B
C
D
E
Jusqu'à là, on a vu comment modifier un élément (une balise existante sur une page). Par exemple, on a changé sa couleur (avec ...style=).
Créez le fichier ajouter.html :
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8"/>
<title>Ajouter</title>
</head>
<body>
<input type="button" />
<script>
let bouton=document.querySelector('input');
bouton.addEventListener('click',ajouter_splat);
function ajouter_splat()
{
...
}
</script>
</body>
</html>
Complétez ce fichier pour que l'image suivante soit ajoutée au body chaque fois que l'utilisateur clique sur le bouton.
Url de l'image: https://moodle.iutv.univ-paris13.fr/img/bjs/splat.png
Pour rappel:
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8"/>
<title>Ajouter</title>
</head>
<body>
<input type="button" value="Appuyer"/>
<script>
let bouton=document.querySelector('input');
bouton.addEventListener('click',ajouter_splat);
function ajouter_splat(e)
{
let i=document.createElement('img');
i.src='https://moodle.iutv.univ-paris13.fr/img/bjs/splat.png';
document.body.append(i);
}
</script>
</body>
</html>
On peut voir le HTML correspondant au DOM du navigateur.
Appuyez plusieurs fois sur le bouton pour créer des images.
Cliquez-droit sur une des images et choisissez "Inspecter".
En bas, dans l'onglet "Inspecteur" vous verrez le HTML des images crées.
Prenez le temps de vous familiariser avec cet onglet. Il est très utile !
Dans les pages suivantes on va écrire, ensemble, étape par étape, un petit programme qui ajoute des images là où on clique.
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8"/>
<title>Pingouin</title>
<style>
</style>
</head>
<body>
<img src="https://moodle.iutv.univ-paris13.fr/img/bjs/tux.png" alt="tux"/>
<p>
bla bla bla bla
<img class="splat" src="https://moodle.iutv.univ-paris13.fr/img/bjs/splat.png" alt="splat"/>
bla bla bla
</p>
<script>
...
</script>
</body>
</html>
On voudrait pouvoir positionner l'image "splat.png" en indiquant des coordonnées x et y.
Pour pouvoir le faire on utilise la propriété CSS "position".
Quand un élément (ici l'image) a « position: absolute », il n'affecte plus du tout le positionnement des autres éléments ou texte autour. Il s'affiche donc « par-dessus » ou « par-dessous » les éléments l'entourant.
Tout seul « position: absolute » n'est pas utile ici. Par contre, une fois qu'un élément est « position: absolute », on peut le déplacer facilement avec les propriétés CSS "left" et "top" (ce qui correspond à x et y):
Dans le HTML ici:
<img class="splat" src="https://moodle.iutv.univ-paris13.fr/img/bjs/splat.png" alt="splat"/>
remarquez class="splat".
On veut pouvoir distinguer, en CSS et en JS, les images du pingouin des "splat". Cette "class" va nous permettre de le faire.
Que faut-il écrire en CSS pour mettre tous les éléments ayant la classe splat en position absolute ?
(Répondez en une seule ligne)
Pas tout à fait. Voici un rappel:
Ajoutez entre les balises <style> de pingouin.html :
.splat
{
position: absolute;
}
Vérifiez que l'image s'affiche maintenant par dessus le texte "bla bla bla ..."
Essayez ensuite aussi plusieurs valeurs pour les propriétés CSS top et left.
N'oubliez pas l'unité "px".
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8"/>
<title>Ajouter</title>
</head>
<body>
<input type="button" value="Appuyer"/>
<script>
let bouton=document.querySelector('input');
bouton.addEventListener('click',ajouter_splat);
function ajouter_splat(e)
{
let i=document.createElement('img');
i.src='https://moodle.iutv.univ-paris13.fr/img/bjs/splat.png';
document.body.append(i);
}
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8"/>
<title>Pos click</title>
</head>
<body>
<p>
La souris se trouve à la position
x=<span id="affiche-x">?</span>,
y=<span id="affiche-y">?</span>
</p>
<script>
document.addEventListener('click',fonction_a_appeler);
function fonction_a_appeler(event)
{
console.log('coucou',event.pageX,event.pageY);
let ax=document.querySelector('#affiche-x');
let ay=document.querySelector('#affiche-y');
ax.textContent=event.pageX;
ay.textContent=event.pageY;
}
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8"/>
<title>Pingouin</title>
<style>
.splat
{
position: absolute;
}
</style>
</head>
<body>
<img src="https://moodle.iutv.univ-paris13.fr/img/bjs/tux.png" alt="tux"/>
<script>
document.addEventListener('click',ajouter_splat);
function ajouter_splat(e)
{
let i=document.createElement('img');
i.src='https://moodle.iutv.univ-paris13.fr/img/bjs/splat.png';
document.body.append(i);
}
</script>
</body>
</html>
On a réussi à ajouter les images!
Maintenant, il ne reste plus qu'a modifier les propriétés de chaque image splat crée dans ajouter_splat pour :
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8"/>
<title>Ajouter</title>
</head>
<body>
<input type="button" value="Appuyer"/>
<script>
let bouton=document.querySelector('input');
bouton.addEventListener('click',ajouter_splat);
function ajouter_splat(event)
{
let i=document.createElement('img');
i.src='https://moodle.iutv.univ-paris13.fr/img/bjs/splat.png';
document.body.append(i);
}
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8"/>
<title>Pos click</title>
</head>
<body>
<p>
La souris se trouve à la position
x=<span id="affiche-x">?</span>,
y=<span id="affiche-y">?</span>
</p>
<script>
document.addEventListener("click",fonction_a_appeler);
function fonction_a_appeler(event)
{
console.log('coucou',event.pageX,event.pageY);
let ax=document.querySelector("#affiche-x");
let ay=document.querySelector("#affiche-y");
ax.textContent=event.pageX+'px';
ay.textContent=event.pageY+'px';
}
</script>
</body>
</html>
bouton.html
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8"/>
<title>Bouton</title>
</head>
<body>
<input type="button" value="Appuyer"/>
<p>
Bonjour!
</p>
<script>
let bouton=document.querySelector('input');
bouton.addEventListener('click',fonction_a_appeler);
function fonction_a_appeler()
{
let paragraphe=document.querySelector('p');
paragraphe.style.color='red';
}
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8"/>
<title>Pingouin</title>
<style>
.splat
{
position: absolute;
}
</style>
</head>
<body>
<img src="https://moodle.iutv.univ-paris13.fr/img/bjs/tux.png" alt="tux"/>
<script>
document.addEventListener('click',ajouter_splat);
function ajouter_splat(event)
{
let i=document.createElement('img');
i.src='https://moodle.iutv.univ-paris13.fr/img/bjs/splat.png';
i.className='splat';
i.style.top =event.pageY+'px';
i.style.left=event.pageX+'px';
document.body.append(i);
}
</script>
</body>
</html>
Actuellement, on utilise le type d'événement "click".
Le click se produit quand l'utilisateur enfonce puis relâche le bouton de la souris.
C'est un petit plus rapide et agréable pour l'utilisateur si on réagit dès qu'il enfonce le bouton (sans attendre qu'il le relâche).
Comment s’appelle ce type événement ?
Actuellement, le coin supérieur gauche de l'image est affiché là où l'utilisateur clique.
Le centre du splat est à environ 16px de la gauche et du haut de l'image splat.png
Rectifiez le JS pour que le splat soit centré.
Un autre tout petit détail: ajoutez aussi la ligne suivante dans ajouter_splat :
event.preventDefault();Elle évite qu'une sélection ne démarre si on bouge la souris en cliquant.
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8"/>
<title>Pingouin</title>
<style>
.splat
{
position: absolute;
top: 500px;
left: 100px;
}
</style>
</head>
<body>
<img src="https://moodle.iutv.univ-paris13.fr/img/bjs/tux.png" alt="tux"/>
<script>
document.addEventListener('mousedown',ajouter_splat);
function ajouter_splat(event)
{
event.preventDefault();
let i=document.createElement('img');
i.src='https://moodle.iutv.univ-paris13.fr/img/bjs/splat.png';
i.className='splat';
i.style.top =(event.pageY-16)+'px';
i.style.left=(event.pageX-16)+'px';
document.body.append(i);
}
</script>
</body>
</html>
Cette partie est juste pour s'amuser. Elle n'est pas à retenir.
On va utiliser les transitions CSS pour animer le splat quand il apparaît.
Pour simplifier, les transitions permettent d'animer certaines valeurs CSS lorsqu'elles changent.
On voudrait faire partir le splat d'en bas de l'écran et le faire bouger vers la position qui a été cliquée: on va donc faire transitionner les propriétés CSS "top" et "left"
On voudrait aussi faire un effet de perspective, en faisant diminuer progressivement la taille du splat: on va utiliser le CSS "transform: scale(4); " et on va le transitionner vers "scale(1)"
Concrètement, modifiez le <style>:
.splat
{
position: absolute;
/* La position de départ: en bas, au centre */
top: 500px;
left: 100px;
/* Agrandir 4 fois l'image */
transform: scale(4);
/* Définir les propriétés CSS à animer. Toutes en 1 seconde */
transition: top 1s,left 1s,transform 1s;
}
Ce CSS définit le point de départ de l'animation. C'est quand on crée l'image dans le JS qu'il va faloir indiquer le point d'arrivée de l'animation.
Il n'y a pas grande chose à changer dans le code (juste 2 lignes à ajouter, et l'ordre à modifier):
document.addEventListener('mousedown',ajouter_splat);
function ajouter_splat(event)
{
event.preventDefault();
let i=document.createElement('img');
i.src='https://moodle.iutv.univ-paris13.fr/img/bjs/splat.png';
i.className='splat';
document.body.append(i);
// Forcer le navigateur à prendre en compte la situation actuelle (position, scale).
// Ceci permettra au navigateur de s'apercevoir d'un changement futur des propriétés CSS.
window.getComputedStyle(i).top;
// Changer les propriétés CSS qui transitionnent.
// Le navigateur s’aperçoit du changement et déclenche la transition.
i.style.top =(event.pageY-16)+'px';
i.style.left=(event.pageX-16)+'px';
i.style.transform='scale(1)';
}
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8"/>
<title>Pingouin</title>
<style>
.splat
{
position: absolute;
/* La position de départ: en bas, au centre */
top: 500px;
left: 100px;
/* Agrandir 4 fois l'image */
transform: scale(4);
/* Définir les propriétés CSS à animer. Toutes en 1 seconde */
transition: top 1s,left 1s,transform 1s;
}
</style>
</head>
<body>
<img src="https://moodle.iutv.univ-paris13.fr/img/bjs/tux.png" alt="tux"/>
<script>
document.addEventListener('mousedown',ajouter_splat);
function ajouter_splat(event)
{
// Petit détail: éviter la sélection
event.preventDefault();
let i=document.createElement('img');
i.src='https://moodle.iutv.univ-paris13.fr/img/bjs/splat.png';
i.className='splat';
document.body.append(i);
// Forcer le navigateur à prendre en compte la situation actuelle (position, scale).
// Ceci permettra au navigateur de s'apercevoir d'un changement futur des propriétés CSS.
window.getComputedStyle(i).top;
// Changer les propriétés CSS qui transitionnent.
// Le navigateur s'aperçoit du changement et déclenche la transition.
i.style.top =(event.pageY-16)+'px';
i.style.left=(event.pageX-16)+'px';
i.style.transform='scale(1)';
}
</script>
</body>
</html>
N'hésitez pas à expérimenter avec ce code !
PS. pauvre pingouin...