des matières
Introduction 1.1
Chapitre 1 - Les Bases 1.2
Chapitre 2 - Algorithmes et Jeux 1.3
Chapitre 3 - Types avancés 1.4
Chapitre 4 - Manipuler le Web avec DOM 1.5
ﺗﻢ
Chapitre 5 - Manipuler les classes et styles CSS 1.6
اﻟﺘ
Chapitre 6 - Composants et POO 1.7
ﺤﻤﻴ
Chapitre 7 - Manipulation DOM avancée 1.8
ﻞﻣ
Chapitre 8 - Échanges de données avec AJAX 1.9
ﻦﻣ
Chapitre 9 - Identification avec Google et Facebook 1.10
Chapitre 10 - jQuery, Node.js et frameworks ﻮﻗﻊ 1.11
Chapitre 11 - Gestion d'erreurs et Geolocation API 1.12
ﺗﻌﻠ
ﻢ اﻟ
ﱪﻣ
ﺠﻪ
ﻣﻦا
ﻟﺒﺪ
اﻳﻪ
إﱃ
اﻹ
ﺣﱰ
اف
Cours JavaScript
Chapitre 1 - Les bases
ﺗ
Chapitre 2 - Algorithmes et jeux
ﻢا
Chapitre 3 - Types avancés
ﻟﺘﺤ
Chapitre 4 - Manipuler le Web avec DOM
ﻤﻴﻞ
Chapitre 5 - Manipuler les classes et styles CSS
Chapitre 6 - Composants et POO
ﻣﻦ
Chapitre 7 - Manipulation DOM avancée
ﻣ
Chapitre 8 - Échanges de données avec AJAX ﻮﻗﻊ
Chapitre 9 - Identification avec Google et Facebook
ﺗ
Chapitre 10 - jQuery, Node.js et frameworks
ﻌﻠﻢ
Tests et corrigés
ﻪ
ﻣﻦ
Partiel 1: Solutions
اف
Ressources alternatives
https://altkowa.blogspot.com ﺗﻢ اﻟﺘﺤﻤﻴﻞ ﻣﻦ ﻣﻮﻗﻊ ﺗﻌﻠﻢ اﻟﱪﻣﺠﻪ ﻣﻦ اﻟﺒﺪاﻳﻪ إﱃ اﻹﺣﱰاف2
Introduction
ﺗﻢ
You-Dont-Know-JS, free book series on JavaScript
JS Books
اﻟﺘ
ﺤﻤﻴ
JavaScript basics, videos by Beau Carnes + challenges on freeCampCode
ﻞﻣ
Ressources annexes au cours
ﻦﻣ
ﻮﻗﻊ
Apprendre à apprendre: deux modes d’apprentissage
Startup Noob Guide
ﻢ ﺗﻌﻠ
اﻟﱪ
ﻣﺠ
ﻪﻣ
ﻦا
ﻟﺒﺪ
اﻳﻪ
إﱃ
اﻹ
ﺣﱰ
اف
ﺗﻢ
Conseil pratique: pour naviguer dans ce cours, vous pouvez y rechercher un mot (ex:
اﻟﺘ
"exercice") en pressant Ctrl-F ou Cmd-F . Utilisez la table des matières pour passer
ﺤﻤﻴ
d'un chapitre à l'autre.
ﻞ
ﻣﻦ
Introduction à la Programmation et à
JavaScript ﻣﻮﻗ
ﻊﺗ
ﻌﻠﻢ
Slides du TP 1
اﻟﱪ
Langage de programmation
ﻣﺠ
ﻪﻣ
JavaScript est un langage qui permet de donner des ordres (appelés instructions) à une
machine.
ﻦا
ﻟﺒﺪ
un navigateur web
إﱃ
un ordinateur
اﻹ
voire même une carte à puce ! (ex: carte SIM, carte bleue...)
On va donc apprendre des commandes et structures pour expliquer ce qu'on attend de cette
machine.
ﺗ
ﻢا
ﻟﺘﺤ
ﻤﻴﻞ
ﻣﻦ
Comme dans une recette, si votre code source est trop vague ou contient des erreurs, le
ﻣ
ﻮﻗﻊ
résultat risque d'être décevant, voire complètement à côté de la plaque.
Contrairement à une recette de cuisine, il faut garder en tête que ce n'est pas un humain qui
ﺗ
ﻌﻠﻢ
va interpréter votre code source, mais une machine. Sachant que, contrairement à un
humain, une machine n'est pas capable de raisonner intuitivement, il faut être extrêmement
اﻟﱪ
Si vous écrivez votre code de manière approximative, deux choses peuvent se passer:
si vous avez de la chance, la machine vous avertira qu'elle n'a pas compris une de vos
instructions => elle affichera un message d'erreur pour vous aider à la corriger;
soit, dans certains cas, il ne se passera rien de visible. Dans ce cas, ce sera à vous de
ﺗ
ﻢا
ﻟﺘﺤ
ﻤﻴﻞ
ﻣﻦ
ﻣﻮﻗ
ﻊﺗ
ﻌﻠﻢ
اﻟﱪ
ﻣﺠ
ﻪﻣ
ﻦا
ﻟﺒﺪ
اﻳﻪ
إﱃ
inclus en standard dans les navigateurs web. On dit donc que c'est "le langage du web".
اف
Même si le nom ressemble, Java est un langage différent de JavaScript. Si vous avez
la flemme de prononcer "JavaScript", utilisez donc ses initiales "JS" plutôt que "Java".
Malgré ses nombreuses évolutions, JavaScript est plutôt un langage de script qu'un langage
de programmation, à proprement parler. En effet, il a été conçu comme une solution simple
pour ajouter des interactions aux pages HTML du web, et non pour créer des logiciels à haut
niveau de sûreté. Une des conséquences: c'est un langage faiblement typé. Nous allons voir
ça plus bas.
ﺗﻢ
2. de manière programmative: en rédigeant un code source
ا
ﻟﺘﺤ
Dans le premier cas, chaque instruction sera exécutée immédiatement puis retournera un
ﻤﻴﻞ
résultat, comme sur une calculatrice.
ﻣﻦ
ﻣﻮﻗ
ﻊﺗ
ﻌﻠﻢ
اﻟﱪ
ﻣﺠ
ﻪﻣ
ﻦا
ﻟﺒﺪ
اﻳﻪ
إﱃ
Dans le deuxième cas, on va écrire une liste d'instructions dans un fichier (appelé "code
اﻹ
source"), pour que notre machine puisse exécuter ce fichier en une seule fois.
ﺣﱰ
Ouvrez une fenêtre de navigation privée (mode incognito) depuis Google Chrome,
ouvrez la console JavaScript en utilisant le raccourci clavier Cmd + Alt + J (sur Mac)
ou Ctrl + Shift + J (sur PC/Window)
tapez 1+1 et validez. => La console devrait afficher le résultat de cette opération.
Ensuite tapez alert('bonjour'); et observez ce qui se passe.
ﺗﻢ
اﻟﺘ
ﺤﻤﻴ
ﻞﻣ
ﻦﻣ
Il existe de nombreuses consoles JavaScript plus ou moins évoluées: repl.it, glot.io,
jsbin, jsfiddle, et codepen permettent d'éditer son code de manière un peu plus
ﻮﻗﻊ
confortable mais ne conservent pas d'historique de vos instructions, contrairement à la
ﺗﻌﻠ
console de Google Chrome.
ﱪ ﻢ اﻟ
Manipulation de valeurs
ﻣﺠ
ﻪﻣ
Types de valeurs
ﻦا
ﻟﺒﺪ
En langue Française, il existe plusieurs types de mots: les noms, les verbes, les adjectifs,
اﻳﻪ
différents types.
Types simples
booléen (boolean): true , false
nombre (integer/float number): 999 , 0.12 , -9.99
chaîne de caractères (string): 'coucou'
aucune valeur: null
Types avancés
ﺗﻢ
opération.
ا
ﻟﺘﺤ
2) Vérifiez vos réponses en saisissant ces opérations dans la console, et en utilisant le mot
ﻤﻴﻞ
clé typeof . (voir plus bas)
ﻣﻦ
0
ﻣﻮﻗ
true
2 - 1.2
ﻊﺗ
'hello'
ﻌﻠﻢ
'bonjour' + 4
{ a: 0.4 }
[ 'a', 'b', 'c' ]
اﻟﱪ
ﻣﺠ
Solution
اﻳﻪ
إﱃ
Dans l'exercice ci-dessus, nous avons manipulé des valeurs de manière littérale. C'est à
dire qu'elles étaient explicitement affichées dans le code.
Dans un véritable programme, les valeurs dépendent souvent d'une saisie de l'utilisateur, ou
d'autre chose. Du coup, elles sont rarement exprimées de manière littérale. On utilise pour
ça une représentation symbolique: les variables.
En maths, on représente habituellement une variable sous forme d'une lettre minuscule. Par
exemple "soit x=4" veut dire qu'on définit une variable appelée x représente actuellement
la valeur 4 . (un nombre entier, en l'occurrence)
En JavaScript, une variable représentée par une suite de lettres (minuscules et/ou
majuscules) pouvant contenir aussi des chiffres et le symbole underscore ( _ ).
Généralement, on emploie une notation appelée camel case pour nommer les variables en
JavaScript. Cette notation consiste à coller plusieurs mots, en mettant en majuscule
seulement la première lettre de chaque mot, sauf celle du premier mot.
Opérateur d'affectation
ﺗ
ﻢا
ﻟﺘﺤ
Comme en maths, l'opérateur d'affectation = permet d'affecter une valeur (à droite) à une
ﻤﻴﻞ
variable (à gauche).
Par exemple, si on tape monNombre = 1 dans une console JavaScript, puis qu'on y tape
ﻣﻦ
monNombre , la console nous répondra 1 car c'est la valeur actuelle de la variable
monNombre .
ﻣﻮﻗ
ﻊﺗ
Chaque usage de l'opérateur d'affectation sur une variable changera sa valeur actuelle,
ﻌﻠﻢ
JavaScript nous répondra 2 car c'est la dernière valeur qui a été affectée à la variable
ﻪ
monNombre .
ﻣﻦ
La valeur affectée (à droite du = ) peut être une valeur littérale, ou celle d'une autre
اﻟﺒ
variable.
ﺪ
اﻳﻪ
autreNombre .
اف
À noter que l'opérateur d'affectation se comporte différemment selon que la valeur affectée
est de type simple (nombre, chaîne de caractères...) ou avancé (objet, tableau, fonction...):
l'affectation d'une valeur de type simple dupliquera cette valeur dans la variable
affectée;
alors qu'en affectant une valeur de type avancé, notre variable affectée sera en fait une
référence à cette valeur.
maValeurSimple = 1;
autreValeurSimple = maValeurSimple;
// à ce stade, nos deux variables valent 1
maValeurSimple = 2;
// => autreValeurSimple vaut toujours 1, alors que maValeurSimple vaut 2
monTableau = [ 1, 2, 3 ];
autreVariable = monTableau;
// à ce stade, nos deux variables valent [ 1, 2, 3 ]
ﺗﻢ
monTableau = [ 4, 5, 6 ];
// cette instruction a affecté un autre tableau à monTableau
اﻟﺘ
// => autreValeurSimple vaut toujours [ 1, 2, 3 ], car il référence toujours le tablea
ﺤ
u qui lui avait été affecté
ﻤﻴﻞ
ﻣﻦ
Exemple d'affectation de valeur de type avancé, avec modification:
monTableau = [ 9, 8, 7 ];
ﻣﻮﻗ
ﻊﺗ
autreVariable = monTableau;
// à ce stade, nos deux variables valent [ 9, 8, 7 ]
ﻌﻠﻢ
monTableau.sort();
// cette instruction a rangé notre tableau dans l'ordre croissant
اﻟﱪ
Création de variable
ﺪاﻳ
ﻪإ
Dans nos exemples, les variables ont été créées automatiquement par la console JavaScript
ﱃ
Mais nous allons désormais créer nos variables de manière explicite, à l'aide du mot-clé
ﺣﱰ
var .
اف
En effet, l'usage de var permet de s'assurer qu'on a pas déjà créé une variable du même
nom.
Il est possible d'affecter une valeur à notre variable lors de sa création avec var .
Exemple:
j'ai ajouté des espaces autour de l'opérateur d'affectation pour améliorer la lisibilité de
mon code;
et j'ai terminé mes instructions par un point-virgule ( ; ).
ﺗﻢ
Afin d'améliorer la lisibilité de votre code, et d'éviter tout ambiguïté pouvant occasionner des
ﺤ اﻟﺘ
erreurs, je compte sur vous pour appliquer ces règles.
ﻤﻴﻞ
Exercice: Création de variables
ﻣﻦ
ﻣﻮﻗ
En utilisant la console JavaScript: ﻊﺗ
1) Créez les variables suivantes:
ﻌﻠﻢ
2) Pour confirmer que vos variables sont correctes, vérifiez que chaque instruction ci-
اﻟﺒ
monNombre === 4;
maChaine === 'bonjour ! :-)';
ﱃ
Solution
Un programme est sensé pouvoir prendre des décisions de manière autonome, sur la base
de conditions.
Pour exprimer ces conditions, on s'appuie généralement sur des comparaisons entre
valeurs. Nous allons commencer par la comparaison la plus simple: l'égalité de valeurs.
Une égalité laxiste consiste à dire que deux valeurs sont vues comme équivalentes, mais
ﺗ
pas exactement égales.
ﻢا
ﻟﺘﺤ
Exemple: 1 (nombre) et "1" (chaîne de caractères) représentent tous les deux le
ﻤﻴﻞ
chiffre 1 , mais sont de types différents => ils sont égaux seulement selon l'opérateur
d'égalité laxiste.
ﻣﻦ
L'égalité stricte vérifie en plus que le type des deux valeurs comparées est le même.
les valeurs à proprement parler qui sont comparées, mais la référence vers cette valeur.
اﻹ
Explication:
ﺣﱰ
اف
[1,2] == [1,2]; // => false, car deux tableaux ont été créés
monTab == [1,2]; // => false, car ce sont deux références de tableaux différents
ATTENTION !
Notez que les opérateurs de comparaison d'égalité == et === ne doivent pas être
confondus avec l'opérateur d'affectation = .
Vous verrez plus tard que se tromper d'opérateur peut causer des erreurs silencieuses qui
peuvent mettre des heures à être détectées et corrigées dans votre code !
Donc soyez attentifs à bien les différencier quand vous écrivez votre code.
Opérateurs d'inégalité
Quand on sait que deux valeurs ne sont pas égales, notre programme peut s'adapter à
ﺗ
différents cas de figure.
ﻢا
ﻟﺘﺤ
Nous avons vu que les opérateurs === et == permettaient d'évaluer l'égalité (stricte ou
ﻤﻴﻞ
laxiste), en retournant une valeur true quand c'était le cas. Le langage JavaScript fournit
aussi leurs opérateurs contraires: !== et != (strict, et laxiste, respectivement). Ceux-ci
ﻣﻦ
retournent une valeur true quand les valeurs comparées ne sont pas égales.
ﻣ
Exemples:
ﺗ ﻮﻗﻊ
1 == 1; // => true
ﻌﻠﻢ
1 != 1; // => false
ﻪ
Exemples:
Conditions
ﺗﻢ
Dans un programme (codé en langage JavaScript ou pas), les conditions sont une des
اﻟﺘ
ﺤﻤﻴ
instructions les plus incontournables.
ﻞﻣ
C'est grâce aux conditions que votre programme peut prendre des décisions et donc
d'effectuer des actions de manière autonome (ou automatique), en fonction des données qui
ﻦﻣ
lui sont fournies.
ﻮﻗﻊ
On peut représenter ces décisions sous forme d'un arbre:
ﺗﻌﻠ
ﻢ
اﻟﱪ
ﻪ ﻣﺠ
ﻣﻦ
ﺪ اﻟﺒ
اﻳﻪ
إﱃ
اﻹ
ﺣﱰ
اف
sinon, si ...
ﺗﻢ
اﻟﺘ
ﺤﻤﻴ
En JavaScript, les conditions s'expriment à l'aide des mots-clés if et else . On les
emploie de la manière suivante:
ﻞﻣ
ﻦﻣ
if (expression) {
// si expression == true, alors les instructions entre ces accolades vont s'exécuter
} else { ﻮﻗﻊ
// sinon, ce sont les instructions entre ces accolades là qui vont s'exécuter
ﺗﻌﻠ
}
ﻢ اﻟ
Exemple:
اﻟﺒ
ﺪاﻳ
ﻪإ
} else {
ﺣﱰ
resultat;
// => cette liste d'instructions va afficher 'monNombre vaut 1'
A retenir: dans un bloc if-else , soit les instructions entre la première paire
d'accolades sera exécuté, soit celles de la deuxième paire d'accolades.
Par ailleurs, observez bien la manière d'agencer les accolades et les espaces.
Dans le cas où vous aimeriez définir plus de deux comportements alternatifs, vous pouvez
employer ajouter des cas else if() entre votre bloc if{} et votre bloc else{} .
Exemple:
if (monNombre === 1) {
resultat = 'monNombre vaut 1';
} else if (monNombre > 1) {
resultat = 'monNombre est supérieur à 1';
} else {
resultat = 'monNombre n\'est ni égal à 1, ni supérieur à 1';
}
ﺗ
resultat;
ﻢا
ﻟﺘﺤ
Comme pour les blocs if-else , seules les instructions d'une paire d'accolades seront
ﻤﻴﻞ
exécutées.
ﻣﻦ
Par contre, si vous écrivez plusieurs blocs if-else à la suite les uns des autres, ceux-ci
ﻣﻮﻗ
seront complètement indépendants. ﻊﺗ
Instructions pour interagir avec l'utilisateur: prompt et
ﻌﻠﻢ
alert
اﻟﱪ
Maintenant qu'on a vu comment faire en sorte qu'un programme prenne des décisions, il
ﻣﺠ
alert('Bonjour !');
اف
Comme vous le voyez, il faut fournir le message à afficher entre parenthèses. Et,
comme il s'agit ici d'une chaîne de caractères littérale, il ne faut pas oublier de mettre le
texte entre apostrophes.
Maintenant, voici comment inviter l'utilisateur à saisir une chaîne de caractères, puis
l'afficher:
Êtes vous capable d'interpréter ce que signifie le code à l'intérieur des parenthèses du
alert ? On appelle ça "la concaténation". On verra ça plus en détail dans les cours à
venir.
ﺗﻢ
Exercice 1: Chat-bot bête mais poli
اﻟﺘ
ﺤﻤﻴ
Écrivez et testez un programme qui va inviter l'utilisateur à saisir une phrase, et se
comporter différemment selon sa saisie:
ﻞﻣ
si l'utilisateur saisit bonjour , afficher Bonjour à toi ! ;
ﻦﻣ
sinon, si l'utilisateur saisit tu vas bien ? , afficher Bien, et toi ? ;
et sinon, afficher Désolé, je n'ai pas compris... . ﻮﻗﻊ
ﺗﻌﻠ
Solution
ﻢ
اﻟﱪ
invitera l'utilisateur à saisir une deuxième réponse puis se comportera différemment selon
ﺪ
1. Dessiner un arbre représentant un total de 5 questions qui pourront être posées par
votre chat-bot, ainsi que les réponses associées pour chaque cas. L'arbre doit avoir au
moins 2 niveaux de profondeur (c.a.d. degré 2).
2. Implémenter et tester les lignes de code JavaScript permettant d’interagir avec le chat-
Vous devrez utiliser les mots clés: var , if , else , = , === , prompt et alert .
ﺗﻢ
Pour cela, je vous recommande d'utiliser une plate-forme de développement de chat-bot, ou
اﻟﺘ
de partir d'un exemple. (ex: https://bottr.co/)
ﺤ
ﻤﻴﻞ
Combinaison d'expressions conditionnelles && et ||
ﻣﻦ
Dans l'exemple précédent, on a vu que chaque alternative dépendait du résultat d'une seule
expression de comparaison de valeurs. ﻣﻮﻗ
ﻊﺗ
ﻌﻠﻢ
Dans certains cas, une alternative est définie par la combinaison de plusieurs expressions.
ﻪ
ﻣﻦ
Mais il est aussi possible d'exprimer nos critères de manière plus linéaire, en combinant les
conditions à l'aide de l'opérateur && :
Dans cette implémentation, nous avons combiné les critères de temps et de temperature
ﺗﻢ
dans une même expression conditionnelle.
اﻟﺘ
ﺤﻤﻴ
Lorsqu'une alternative if/else est définie par plusieurs expressions liées par l'opérateur
ﻞﻣ
&& (appelé et), il faut que toutes ces expressions soient vraies afin que les instructions
ﻦﻣ
Il existe aussi un opérateur || (appelé ou) qui permet de définir des alternatives qui seront
ﻮﻗﻊ
exécutées si au moins une des expressions est vraie.
ﺗ
ﻌﻠﻢ
Exemple:
اﻟﱪ
}
ﻟﺒﺪ
اﻳﻪ
} else {
message = 'nous pouvons en discuter tout de suite, si vous voulez !';
}
Dans ce cas, nous voyons que la combinaison d'expression conditionnelle avec || permet
de réduire la redondance de notre code, en ne définissant qu'une seule fois une même liste
d'instructions correspondante à deux cas alternatifs.
Dans le cadre de ce cours, nous allons respecter un extrait des conventions du guide de
style d'Airbnb. (c'est illustré de nombreux exemples très clairs qui aident à comprendre les
bonnes et mauvaises manières d'écrire son code)
Pour vérifier et corriger l'indentation de votre code JavaScript, vous pouvez utiliser l'outil en
ligne jsbeautifier.
ﺗ
ﻢا
Si vous préférez utiliser votre éditeur de code préféré (ex: sublime text) pour vous aider à
ﻟﺘﺤ
corriger l'indentation et/ou les conventions ci-dessus, configurez-le de manière à ce qu'il
ﻤﻴﻞ
respecte le guide de style d'Airbnb.
ﻣ ﻣﻦ
ﺗ ﻮﻗﻊ
ﻌﻠﻢ
اﻟﱪ
ﻪ ﻣﺠ
ﻣﻦ
اﻟﺒ
ﻪ ﺪاﻳ
إﱃ
اﻹ
ﺣﱰ
اف
ﺗﻢ
Savoir développer les jeu ChiFouMi (pierre feuille ciseaux)
اﻟﺘ
Création d'algorithmes à l'aide de boucles, et de fonctions
ﺤﻤﻴ
Plan du chapitre:
ﻞﻣ
1. Algorithmes
ﻦﻣ
2. Boucles for (Slides du TP)
Application: FizzBuzz
ﻮﻗﻊ
Application: Devine le nombre
ﺗﻌﻠ
3. Fonctions (Slides du TP)
ﻢ
1. Algorithmes
ﻟﺒﺪ
اﻳﻪ
Définition de Wikipedia
إﱃ
اﻹ
Une recette de cuisine peut être réduite à un algorithme, si on peut réduire sa spécification
aux éléments constitutifs :
Un casse-tête, tel le Rubik's Cube, peut être résolu de façon systématique par un algorithme
qui mécanise sa résolution.
2. Boucles for
ﺗﻢ
اﻟﺘ
ﺤﻤﻴ
Qu'est-ce qu'une boucle ?
ﻞﻣ
Une boucle permet de répeter plusieurs fois une séquence d'instuctions.
ﻦﻣ
Pour afficher les nombres de 1 à 3 dans la console JavaScript, on pourrait utiliser les
instructions suivantes: ﻮﻗﻊ
ﺗﻌﻠ
console.log(1);
ﻢ
console.log(2);
اﻟﱪ
console.log(3);
ﻣﺠ
Par contre, le code deviendrait très fastidieux à écrire (et à lire) dans le cas où on voudrait
اﻟﺒ
Pour ce genre de répétition, le mot-clé for permet de définir une seule fois les instructions
إﱃ
qui doivent êtres répétées, puis de spécifier combien de fois on souhaite qu'elles soient
اﻹ
répétées.
ﺣﱰ
Pour afficher les nombres de 1 à 10000 , il suffit donc d'écrire le code suivant:
اف
Les jeux tour-par-tour consistent en une boucle qui se termine lorsqu'un joueur
remporte la partie;
Les jeux d'action utilisent une boucle permettant de mettre à jour l'affichage (frame par
frame, pour utiliser la terminologie exacte) en fonction des actions du/des joueur(s);
Ainsi que les algorithmes de tri et de manipulation de données utilisés dans 99% des
ﺗﻢ
logiciels.
اﻟﺘ
ﺤﻤﻴ
Javascript fournit quatre mots-clés pour définir des boucles: do , while , until et for .
La forme de boucle la plus courante est for car c'est la plus générique / adaptable. Nous
ﻞﻣ
allons donc seulement travailler avec des boucles for dans le cadre de ce cours.
ﻦﻣ
Anatomie d'une boucle for en JavaScript ﻮﻗﻊ
ﺗﻌﻠ
Reprenons l'exemple de boucle que nous avons vu plus haut:
ﻢ
اﻟﱪ
}
ﻪﻣ
ﻦا
une liste d'instructions (saisie entre accolades {} ) à répéter tant que la condition est
إﱃ
vraie: console.log( monNombre ); (dans notre exemple, il n'y a qu'une seule instruction,
اﻹ
<= 10000 ;
une instruction d'itération qui sera exécutée après chaque itération de la boucle:
monNombre++ (qui, ici, incrémente la valeur de monNombre , c'est à dire augmente sa
valeur de 1 );
et une instruction d'initialisation qui ne sera exécutée qu'une seule fois: var monNombre =
1 (ici, on créée une variable monNombre et on lui affecte la valeur initiale 1 ).
Pour synthétiser, voici la syntaxe à utiliser pour définir une boucle for en JavaScript:
À noter que, dans la plupart des cas, les boucles sont utilisées pour itérer:
ﺗ
ﻢا
Afin de mieux comprendre le fonctionnement de la boucle for et de la manière de saisir
ﻟﺘﺤ
ces trois paramètres, nous allons interpréter une boucle comme le fait un navigateur web
ﻤﻴﻞ
(ou tout autre interpréteur JavaScript).
ﻣﻦ
Prenons la boucle for suivante:
console.log('on va boucler');
ﻣﻮﻗ
ﻊﺗ
for ( var i = 0; i < 4; i++ ) {
console.log('i', i, i < 4);
ﻌﻠﻢ
}
console.log('on a fini de boucler');
اﻟﱪ
ﻣﺠ
ﺗﻢ
i++; // incrémentation => i vaut maintenant 2
اﻟﺘ
ﺤﻤﻴ
// --- troisième itération de la boucle ---
i < 4 ? // condition vraie, car 2 < 4
ﻞﻣ
console.log('i', i, i < 4); // => affiche: i 2 true
i++; // incrémentation => i vaut maintenant 3
ﻦﻣ
// --- quatrième itération de la boucle ---
ﻮﻗﻊ
i < 4 ? // condition vraie, car 3 < 4
console.log('i', i, i < 4); // => affiche: i 3 true
ﺗﻌﻠ
i++; // incrémentation => i vaut maintenant 4
ﻢ اﻟ
Il est très pratique de décomposer une boucle de cette manière lorsqu'elle ne se comporte
ﺪاﻳ
Dans certains cas, il est pratique d'interrompre l'exécution d'une boucle, pendant l'exécution
اف
d'une de ses itérations (tel que définie entre les accolades de définition de la boucle).
Cependant, l'usage de break est non recommandé, car il rend la logique plus complexe à
comprendre en lisant le code. Il est généralement possible et plus élégant d'intégrer la
condition de sortie dans la condition de la boucle.
var commande;
for (var i = 0; i < 10 && commande !== 'quitter'; i++) {
commande = prompt('entrez une commande');
}
Ici, on a intégré la condition à l'aide de l'opérateur logique && , donc la boucle continuera
d'itérer tant que i < 10 ET que commande !== 'quitter' .
ﺗ
ﻢا
ﻟﺘﺤ
Application: FizzBuzz
ﻤﻴﻞ
Algorithme à implémenter
ﻣﻦ
ﻣﻮﻗ
À implémenter étape par étape: ﻊﺗ
1. Écrire un programme qui affiche les nombres de 1 à 199 (compris) dans la console.
ﻌﻠﻢ
2. Pour les multiples de 3 , afficher Fizz au lieu du nombre.
3. Pour les multiples de 5 , afficher Buzz au lieu du nombre.
اﻟﱪ
commencer par écrire la logique d'une seule itération, avant de la faire se répéter à
ﻦا
JavaScript.
إﱃ
اﻹ
1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
ﺗﻢ
14
اﻟﺘ
FizzBuzz
ﺤﻤﻴ
ﻞﻣ
... et ainsi de suite, jusqu'à 199 .
ﻦﻣ
Comment savoir si un nombre est multiple d'un autre ?
ﻮﻗﻊ
Pour savoir si un nombre est multiple de 3 et/ou de 5 , nous allons utiliser deux fonctions
ﺗﻌﻠ
fournies ci-dessous:
ﻢ اﻟ
ﱪﻣ
function estMultipleDeTrois(nombre) {
return nombre % 3 === 0;
ﺠﻪ
}
function estMultipleDeCinq(nombre) {
ﻣﻦ
Après avoir copié-collé la définition de ces deux fonctions dans la console JavaScript, vous
ﱃ
Vous pouvez alors appeler ces fonctions dans les parenthèses de vos conditions if , car,
comme une expression de comparaison de valeurs, un appel de fonction retourne une
valeur qui est vraie ( true ) ou fausse ( false ).
Exemple:
Solution
ﺗﻢ
Fonctionnement du jeu à implémenter
اﻟﺘ
ﺤﻤﻴ
En début de partie, l'ordinateur va choisir un nombre aléatoire entre 0 et 100 .
ﻞﻣ
Le joueur a droit à 10 tentatives pour deviner ce nombre.
À chaque tentative:
ﻦﻣ
Si le nombre saisi est inférieur à celui de l'ordinateur, afficher Plus grand .
ﻮﻗﻊ
Si le nombre saisi est supérieur à celui de l'ordinateur, afficher Plus petit .
Si le joueur a réussi à deviner le bon nombre, afficher Bravo ! .
ﺗ
ﻌﻠﻢ
vous allez avoir besoin d'interagir avec l'utilisateur, et donc d'utiliser les mots-clés
ﻪﻣ
prompt et alert ;
ﻦا
il est recommandé de commencer par écrire le code d'une seule itération (sans
ﻟﺒﺪ
Math.round(Math.random() * 100)
Libre à vous de stocker cette valeur dans une variable, si vous avez besoin de la comparer
à d'autres valeurs, par exemple.
Solution
3. Fonctions
ﺗ
ﻢا
ﻟﺘﺤ
Introduction
ﻤﻴﻞ
Comme en mathématiques, une fonction transforme des paramètres (en "entrée") en une
valeur de résultat (la "sortie"), lorsqu'elle est appelée. Avant de pouvoir l'appeler, on la
ﻣﻦ
définit par une suite d'instructions qui déterminera cette valeur de résultat, en fonction des
ﻣ
paramètres qui lui seront passés. ﻮﻗﻊ
ﻢ ﺗﻌﻠ
اﻟﱪ
Définir une fonction permet de regrouper des instructions JavaScript, afin qu'elles puissent
ﻣﺠ
Par exemple, sur le web, les fonctions JavaScript sont utilisées par le développeur pour
définir le comportement que doit suivre le navigateur lorsque l'utilisateur effectue certaines
ﻟﺒﺪ
actions (ex: saisie dans un champ, clic sur un bouton, soumission d'un formulaire).
اﻳﻪ
إﱃ
Par exemple:
Pour exécuter une fonction, il faut l'appeler en citant son nom, et en lui fournissant des
valeurs pour chacun des paramètres entre parenthèses.
Par exemple:
ﺗﻢ
اﻟﺘ
ﺤﻤﻴ
var resultat = multiplierParDeux(3); // => le paramètre nombre vaut 3 => la variable r
esultat vaudra 6
ﻞﻣ
ﻦﻣ
Comme pour une variable, l'appel à une fonction sera remplacé la valeur qu'elle renvoie, au
moment de l'exécution du programme. Contrairement aux variables, cette valeur dépendra
de la valeur des paramètres passés à la fonction.
ﺗ ﻮﻗﻊ
ﻌﻠﻢ
Ainsi, il est possible de passer le résultat de l'appel d'une fonction en paramètre d'une
fonction.
اﻟ
ﱪﻣ
resultat = 12;
اﻹ
ﺣﱰ
Importance de return
Quand on exécute une fonction depuis une console JavaScript, la valeur retournée par cette
fonction est affichée dans la console. Il ne faut pas pour autant confondre le mot clé return
et la fonction console.log .
En effet:
console.log peut être appelée plusieurs fois depuis un même définition de fonction,
mais chaque appel de fonction ne peut résulter qu'en une seule valeur de retour
spécifiée par return ,
l'usage de return permet à l'appelant d'une fonction de disposer de la valeur
résultante comme il le souhaite: il peut par exemple décider d'afficher cette valeur dans
ﺗ
ﻢا
la console, ou dans un alert , ou même de la stocker dans une variable. Or, si la
définition de cette fonction affiche la valeur résultante dans la console au lieu d'utiliser
ﻟﺘﺤ
return , il sera impossible pour l'appelant de récupérer cette valeur résultante dans
ﻤﻴﻞ
son programme.
ﻣﻦ
Pratique: Définition et appel de fonction
ﻣ
ﻮﻗﻊ
ﺗﻌﻠ
Dans cette partie de mise en pratique, nous allons définir ensemble plusieurs fonctions, et
les tester en les appelant.
ﻢ
اﻟﱪ
Développer:
ﻣ
ﺠﻪ
Tests:
ا
ﻟﺒﺪ
diviserParDeux(2) === 1;
اﻳﻪ
diviserParDeux(4) === 2;
une fonction somme qui retourne la somme des deux paramètres qui lui seront passés.
اﻹ
Tests:
ﺣﱰ
اف
somme(1, 1) === 2;
somme(1, 2) === 3;
somme(2, 1) === 3;
une fonction signe qui retourne la chaîne de caractères positif , négatif ou nul ,
selon le signe de la valeur passée en paramètre. Tests:
une fonction factorielle qui retourne le produit de tous les entiers consécutifs entre 1
et l'entier passé en paramètre (compris). Exemple: factorielle(3) retourne le résultat
de 1 * 2 * 3 , soit 6 . Tests:
factorielle(0) === 0;
factorielle(1) === 1;
factorielle(3) === 6;
Solution
ﺗ
ﻢا
Bugs et tests unitaires: comment tester une fonction
ﻟﺘﺤ
Appeler une fonction ajoute de l'incertitude et parfois de l'imprévisibilité au comportement du
ﻤﻴﻞ
code, car cela revient à déléguer une fonctionnalité à une autre partie du code (la définition
de la fonction appelée).
ﻣﻦ
ﻣﻮﻗ
Afin de se rassurer sur le bon fonctionnement d'une fonction et éviter les bugs, il est
important de tester les fonctions qu'on utilise.
ﻊﺗ
ﻌﻠﻢ
Un bug est un comportement imprévu causant des anomalies et/ou l'interruption de
l'exécution du programme. Il est généralement causé par une erreur d'implémentation ou
اﻟﱪ
une réalisation trop naïve (c.a.d. ne couvrant pas certains cas qui peuvent se produire).
ﻣﺠ
}
اﻳﻪ
Dans l'exemple ci-dessus, nous avons effectué trois tests d'appel de notre fonction
multiplierParDix , et l'un d'eux nous a permis de détecter un bug dans notre fonction.
Afin de réduire le nombre de bugs potentiels d'une fonction, et donc de se rassurer sur son
bon fonctionnement, il est important d'écrire et exécuter plusieurs tests unitaires, et penser
intelligemment aux cas limites, les cas qui pourraient le plus probablement causer un bug.
implémenter l'appel de cette fonction, et comparer la valeur résultante à celle qui est
attendue.
Par exemple, on pourrait définir les trois tests unitaires suivants pour valider notre fonction
multiplierParDix :
ﺗ
ﻢا
ﻟﺘﺤ
Avec la définition de la fonction multiplierParDix fournie plus haut, aucun de ces tests ne
ﻤﻴﻞ
passe. C'est à dire que chaque test d'égalité sera false .
ﻣﻦ
En revanche, les tests unitaires passeront avec la définition suivante de cette même
fonction:
ﻣﻮﻗ
ﻊﺗ
function multiplierParDix (nombre) {
return nombre * 10;
ﻌﻠﻢ
}
multiplierParDix(2) === 20; // => true => OK
اﻟﱪ
À retenir: Un test unitaire est un exemple d'appel permettant de vérifier qu'une fonction
se comporte comme prévu dans un cas donné, en comparant le résultat effectivement
ﻟﺒﺪ
Nous avons vu que l'appel d'une fonction consiste à mentionner son nom, suivi de
اف
paramètres exprimés entre parenthèses. Et que cet appel est remplacé par la valeur
retournée par son exécution.
Pour rappel, une variable Javascript est remplacée par la dernière valeur qui lui a été
affectée. Ainsi, si la valeur 6 a été affectée à la variable maVariable à l'aide de l'instruction
maVariable = 6; , les mentions suivantes de maVariable seront remplacée par sa valeur
6 .
En Javascript, une fonction est une valeur, au même titre qu'un nombre ou une chaîne de
caractères. Elle peut donc aussi être attribuée à une variable.
ﺗ
ﻢا
Ainsi, il est possible d'affecter la fonction multiplierParDeux à la variable maVariable :
ﻟﺘﺤ
ﻤﻴﻞ
maVariable = multiplierParDeux;
ﻣﻦ
...et de l'appeler de la manière suivante:
ﻣ
maVariable(3); // => retourne la valeur 6;
ﻮﻗﻊ
ﻢ ﺗﻌﻠ
Il est donc aussi possible d'affecter une fonction anonyme à une variable:
اﻟﱪ
ﻣﺠ
};
ﻦ اﻟ
return nombre * 3;
اﻹ
}
ﺣﱰ
اف
Un point est donné à celui qui a choisi l'élément le plus fort, sachant que:
Si l'ordinateur et le joueur ont choisi le même élément, aucun d'eux n'emporte de point.
ﺗ
ﻢا
Phase 1: Implémentation d'une manche
ﻟﺘﺤ
ﻤﻴﻞ
Pour implémenter le code d'une manche, nous allons:
définir une fonction comparer(choix1, choix2) qui renvoie le nom de l'élément gagnant,
ﻣﻦ
entre les deux passés en paramètres;
ﻣﻮﻗ
appeler cette fonction, en passant les choix de l'ordinateur et du joueur en paramètres,
ﻊﺗ
afin de savoir lequel des deux a remporté la manche.
ﻌﻠﻢ
Pour vous aider, le site codecademy propose un guide interactif: Créez un "Pierre, feuille,
ciseaux".
اﻟﱪ
ﻣﺠ
Si vous ne souhaitez pas utiliser ce site, voici une proposition d'étapes à suivre:
ﻪ
remporte la manche;
اﻹ
qui retourne le nom de l'élément gagnant à l'aide de return (au lieu de l'afficher dans
اف
7. Faire en sorte que choixOrdi ait pour valeur un des trois éléments, choisi de manière
aléatoire, et que choixUtilisateur soit saisi par l'utilisateur à l'aide de prompt() ;
8. Appeler la fonction comparer() , puis afficher dans la console la valeur de son résultat
(l'élément qui remporte la manche), à partir des choix de l'ordinateur et du joueur.
Pour cela:
ﺗﻢ
3. Mettre le code correspondant à une manche dans une boucle for , de manière à ce
qu'il s'exécute 3 fois d'affilée;
اﻟﺘ
ﺤﻤﻴ
4. En fin de partie, afficher qui a remporté la partie: 'ordi' , 'joueur' ou 'aucun' , en
fonction des scores.
ﻞﻣ
Solution de la phase 1
ﻦﻣ
Solution de la phase 2 ﻮﻗﻊ
ﺗﻌﻠ
ﻢ اﻟ
ﱪﻣ
ﺠﻪ
ﻣﻦا
ﻟﺒﺪ
اﻳﻪ
إﱃ
اﻹ
ﺣﱰ
اف
ﺗﻢ
Savoir développer le Jeu du Pendu, et un répertoire téléphonique
اﻟﺘ
Utilisation de tableaux et d'objets
ﺤﻤﻴ
Plan du chapitre:
ﻞﻣ
1. Tableaux, introduction (Slides du TP)
ﻦﻣ
Application: Calendrier
2. Tableaux, fonctions avancées
ﻮﻗﻊ
Application: Jeu du Pendu
ﺗﻌﻠ
3. Objets JavaScript (Slides du TP)
ﻢ اﻟ
1. Tableaux, introduction
اﻳﻪ
إﱃ
Un tableau (appelé array en anglais) est un type avancé de valeurs. C'est une liste
اﻹ
ordonnée de valeurs.
ﺣﱰ
Exemple:
اف
Caractéristiques
Comme tous les autres types de valeur, un tableau peut être stocké dans une variable.
En revanche, en JavaScript, les tableaux sont considérés comme une forme particulière du
type object . Autrement dit, typeof [] retourne "object" .
Comme toute variable en JavaScript, les valeurs stockées dans un tableau peuvent être de
n'importe quel type (y compris un tableau), et n'ont pas besoin d'être tous du même type:
Tout tableau possède une propriété length qui vaut le nombre de valeurs qu'il contient:
ا ﺗﻢ
ﻟﺘﺤ
Chaque élément d'un tableau est numéroté par ce qu'on appelle un "indice" (ou "index" en
ﻤﻴﻞ
anglais).
ﻣﻦ
Du coup, l'indice du premier élément est 0 , et l'indice du dernier élément est length - 1
( length étant le nombre d'éléments du tableau). ﻣﻮﻗ
ﻊﺗ
On peut accéder à un élément de tableau en précisant son indice entre crochets:
اﻟ ﻌﻠﻢ
fruits[3]; // undefined
ا
ﻟﺒﺪ
اﻳﻪ
Pour modifier la valeur d'un élément, il suffit de l'adresser par indice (comme vu juste avant)
اﻹ
puis de lui affecter une valeur, comme on le ferait pour une variable:
ﺣﱰ
اف
Ajout d'élément
La méthode push() permet d'ajouter un élément à la fin du tableau. La valeur de cet
élément est à passer en paramètre (entre parenthèses) de la méthode, quand on l'appelle:
ﺗ
ﻢا
Retrait d'élément
ﻟﺘﺤ
La méthode pop() retourne la dernière valeur du tableau puis la retire de ce tableau:
ﻤﻴﻞ
ﻣﻦ
var fruits = [ 'Mangue', 'Raisin', 'Figue' ];
var f = fruits.pop();
ﻣﻮﻗ
f; // => `Figue`
fruits; // => [ 'Mangue', 'Raisin' ];
ﻊﺗ
ﻌﻠﻢ
À chaque fois qu'on retire un élément d'un tableau en appelant la méthode pop() , sa
longueur length est décrémentée (c.a.d. sa valeur décroit de 1 ):
اﻟﱪ
ﻣﺠ
Pratique: Calendrier
ﺪاﻟﺒ
اﻳﻪ
Quelles instructions JavaScript faut-il exécuter pour effectuer les opérations suivantes ?
ﺣﱰ
اف
Quelle est la valeur finale du tableau, après avoir effectué toutes ces opérations ?
Solution
ﺗﻢ
اﻟﺘ
Si aucun élément du tableau ne contient la valeur cherchée, l'appel à indexOf() retourne
ﺤﻤﻴ
-1 :
ﻞﻣ
fruits.indexOf('Pomme'); // => -1, car il n'y a pas de valeur 'Pomme' dans fruits
ﻦﻣ
Concaténation de tableaux
ﺗ ﻮﻗﻊ
ﻌﻠﻢ
Comme pour les chaînes de caractères, il est possible de concaténer des tableaux.
اﻟ
La méthode concat() retourne un nouveau tableau contenant les éléments du tableau sur
ﻣﻦ
Il est bien entendu possible d'utiliser des tableaux littéraux, au lieu de variables:
اف
[ 'Mangue', 'Raisin' ].concat([ 'Figue', 'Kiwi' ]); // => [ 'Mangue', 'Raisin', 'Figue
', 'Kiwi' ]
Partitionnement de tableaux
La méthode slice() retourne un nouveau tableau contenant un extrait du tableau sur
lequel elle est appelée.
A chaque appel de cette méthode, il faut fournir deux paramètres: l'indice de l'élément où
commence cet extrait, et l'indice de l'élément où se termine l'extrait (non compris):
Altération de tableau
La méthode splice() (à ne pas confondre avec slice() ) permet à la fois de supprimer et
d'insérer des éléments dans un tableau, en fournissant leur indice(s).
ﺗﻢ
paramètre c : nombre d'éléments à supprimer depuis l'indice i
اﻟﺘ
paramètre(s) suivant(s): valeur(s) d'élément(s) à insérer à partir de l'indice i
ﺤﻤﻴ
Voici un exemple utilisant les paramètres i et c : (suppression seulement)
ﻞﻣ
ﻦﻣ
var fruits = [ 'Mangue', 'Raisin', 'Figue', 'Kiwi' ];
fruits.splice(1, 2); // depuis l'indice 1, supprimer 2 valeurs
fruits; // => [ 'Mangue', 'Kiwi' ]
ﻮﻗﻊ
ﺗﻌﻠ
nouveau tableau, mais modifie le tableau sur lequel elle est appelée.
ﱃ
اﻹ
Pratique: Épicerie
ﺣﱰ
اف
Solution
ﺗ
ﻢا
ﻟﺘﺤ
À chaque tentative, le joueur va proposer une lettre, puis:
ﻤﻴﻞ
si la lettre fait partie du mot à deviner (dont les lettres sont stockées dans le tableau
lettres ), cette lettre sera supprimée du tableau;
ﻣﻦ
sinon, le nombre de tentatives décrémente.
ﻣ
ﻮﻗﻊ
Le joueur gagne la partie quand il a deviné toutes les lettres du mot. (c.a.d. le tableau
lettres ne contient plus aucun élément)
ﻢ ﺗﻌﻠ
Mots clés à utiliser: alert , prompt , if , else , = , === , indexOf , splice , et for
ﻦ اﻟ
Conseil: avant de créer une boucle for , implémenter l'algorithme qui sera exécuté à
chaque itération de cette boucle. (une itération = une tentative du joueur)
ﺒ
ﺪاﻳ
ﻪإ
Étapes proposées:
ﱃ
6. Créer une boucle for permettant de jouer jusqu'à la fin de partie (perdu ou bravo).
BONUS: Dans le cas où le joueur devine une lettre qui apparaît plus d'une fois dans le mot,
retirer toutes les occurrences de cette lettre en une seule fois.
Solution + Bonus
3. Objets JavaScript
Dans la première moitié de ce chapitre nous avons vu que les tableaux permettaient de
stocker une liste ordonnées d'éléments (ayant chacun une valeur de n'importe quel type). Et
que ces éléments étaient indexés par des numéros.
Exemple:
ﺗﻢ
// 1: 'b'
// 2: 4
ا
ﻟﺘﺤ
ﻤﻴﻞ
Les objets permettent aussi de stocker des valeurs.
ﻣﻦ
Alors que chaque valeur d'un tableau est stockée dans un élément, chaque valeur d'un
ﻣﻮﻗ
objet est stockée dans ce qu'on appelle une propriété.
ﻊﺗ
Alors que chaque élément d'un tableau est indexé par un numéro (indice), chaque propriété
ﻌﻠﻢ
d'un objet est indexé par une chaîne de caractères.
اﻟ
Définition d'objet
ﱪﻣ
ﺠﻪ
un objet doit être précédée du nom de cette propriété (aussi appelé clé, ou key en anglais),
et suivi par : (deux points).
ا
ﻟﺒﺪ
اﻳﻪ
var objet = {
إﱃ
prop1: 'a',
prop2: 'b',
اﻹ
prop3: 4,
ﺣﱰ
};
// => Correspondance entre noms de propriétés et leur valeur
اف
// 'prop1': 'a'
// 'prop2': 'b'
// 'prop3': 4
À noter que chaque définition de propriété doit être ponctuée d'une virgule.
Les règles d'indentation s'appliquent aussi à la définition d'objets sur plusieurs lignes, car les
propriétés sont définies entre accolades.
Le format JSON (JavaScript Object Notation, utilisé très couramment par les APIs de
sites web, et exports structurées de données depuis le web) correspond à cette
manière de définir des objets. Nous allons y revenir plus tard dans ce chapitre.
ﺗ
Comme pour les tableaux, l'adressage par crochets a un avantage intéressant: il permet
ﻢا
d'accéder à un élément dont la clé est stockée dans une variable.
ﻟﺘﺤ
ﻤﻴﻞ
Exemple:
ﻣﻦ
var objet = {
prop1: 'a',
prop2: 'b',
prop3: 4, ﻣﻮﻗ
ﻊﺗ
};
ﻌﻠﻢ
La notation pointée est plus concise et lisible, mais impose de mentionner la clé "en dur"
اﻹ
Modification de propriétés
var objet = {
prop1: 'a',
prop2: 'b',
prop3: 4,
};
ﺗ
ﻢا
objet.prop2 = 3; // => objet: { prop1: 'a', prop2: 3, prop3: 4 }
ﻟﺘﺤ
Il est bien sûr possible d'utiliser indifféremment l'adressage par notation pointée ou par
ﻤﻴﻞ
crochets, pour une affectation.
ﻣﻦ
Clés riches
ﻣ
ﻮﻗﻊ
Contrairement aux restrictions imposées pour nommer les variables en JavaScript, il est
ﺗ
ﻌﻠﻢ
possible d'inclure des espaces et des caractères spéciaux dans les noms de propriétés.
اﻟﱪ
Par contre, il faut dans ce cas utiliser des apostrophes (ou guillemets) pour définir et
adresser ces propriétés:
ﻪ ﻣﺠ
ﻣﻦ
var mesAmis = {
'Luke Skywalker': true,
اﻟﺒ
};
اﻳﻪ
Comme pour les tableaux, la valeur d'une propriété d'objet peut être de n'importe quel type:
string , number , boolean , null , undefined , object ou function .
A noter que, comme les objets, les tableaux sont aussi de type object .
Mais les tableaux ont des caractéristiques particulières que n'ont pas les objets. Notamment
l'indexation numérique, des fonctions spécifiques comme slice , etc...
Afin que l'annuaire soit extensible à l'avenir, aucune condition if ne doit être utilisée. Nous
allons donc stocker les noms et numéros de téléphones dans un objet, et utiliser l'adressage
par crochets pour trouver un numéro à partir d'un nom.
ﺗﻢ
اﻟﺘ
Solution
ﺤ
ﻤﻴﻞ
ﻣﻦ
4. Objets, usage avancé
ﻣﻮﻗ
ﻊﺗ
Hiérarchie d'objets
ﻌﻠﻢ
Comme il est possible de stocker un objet comme valeur d'une propriété d'objet, cela veut
اﻟﱪ
Exemple:
ﻪ
ﻣﻦ
var compteFacebook = {
اﻟﺒ
amis: {
ﺪاﻳ
},
ﱃ
groupes: {
اﻹ
maitresJedi: {
ﺣﱰ
},
lolcats: {
titre: 'Vive les chats !',
membres: [ 'Patrick' ],
},
},
};
Dans l'exemple ci-dessus, nous avons jusqu'à trois niveaux d'imbrication d'objets (voire
quatre, si on compte les tableaux comme des objets): l'objet compteFacebook contient une
propriété groupes (de type objet) contenant une propriété maitresJedi (aussi de type
Cet objet peut être représenté visuellement sous forme d'un arbre.
Exemple:
ﺗﻢ
// adressage par crochets:
compteFacebook['groupes']['maitresJedi']['membres'][0]; // (idem)
ﺤ اﻟﺘ
ﻤﻴﻞ
Dans cet exemple aussi, on peut utiliser indifféremment la notation pointée ou les crochets,
pour accéder à la propriété d'un objet.
ﻣﻦ
Énumérer les propriétés d'un objet
ﻣﻮﻗ
ﻊﺗ
Il existe deux manières d'énumérer les propriétés d'un objet:
ﻌﻠﻢ
var mesAmis = {
اﻟﺒ
};
for (var cle in mesAmis) {
ﱃ
}
ﺣﱰ
Contrairement à une boucle for classique (dans laquelle on définit une instruction
d'initialisation, une expression conditionnelle et une instruction d'incrémentation, séparés par
des points-virgules, pour rappel), la boucle for-in va répéter la liste d'instructions entre
accolades pour chaque clé de l'objet.
Dans notre exemple de code ci-dessus, la variable cle prendra donc la valeur d'une clé de
l'objet mesAmis , pour chacune de ses propriétés.
A noter que cela fonctionne aussi sur les tableaux, sauf que l'indice de chaque élément
du tableau sera fourni (au lieu de la clé de chaque propriété de l'objet).
var mesAmis = {
'Luke Skywalker': true,
'Dark Vador': false,
ﺗﻢ
};
اﻟﺘ
var cles = Object.keys(mesAmis); // => [ 'Luke Skywalker', 'Dark Vador' ]
ﺤ
ﻤﻴﻞ
On peut alors utiliser une boucle for plus classique pour itérer sur les valeurs de ce
ﻣﻦ
tableau:
}
// => lignes affichées dans la console:
اﻟﱪ
Pour supprimer une propriété d'un objet, il faut utiliser le mot clé delete de la manière
ﻪإ
suivante:
ﱃ
اﻹ
var objet = {
ﺣﱰ
prop1: 'a',
prop2: 'b',
اف
prop3: 4,
};
delete objet.prop2;
// => objet === { prop1: 'a', prop3: 4 }
liste des contacts de l'annuaire (nom + numéro de téléphone, à afficher dans la console
à l'aide d'une boucle for..in ),
ajout d'un contact (nom + numéro de téléphone) dans l'annuaire,
suppression d'un contact.
Pour permettre à l'utilisateur de choisir la fonctionnalité qu'il souhaite utiliser, lui demander
de saisir la première lettre de la fonction:
ﺗﻢ
et 's' pour supprimer.
اﻟﺘ
Afin que l'utilisateur puisse utiliser plusieurs fonctionnalités d'affilée, placer le code du
ﺤﻤﻴ
programme dans une boucle qui ne s'arrêtera que lorsque l'utilisateur aura tapé q au lieu
ﻞﻣ
de choisir une fonctionnalité.
ﻦﻣ
Solution
ﻮﻗﻊ
ﺗﻌﻠ
ﻢ اﻟ
ﱪﻣ
ﺠﻪ
ﻣﻦا
ﻟﺒﺪ
اﻳﻪ
إﱃ
اﻹ
ﺣﱰ
اف
ﺗﻢ
Exécuter du code JavaScript depuis une page HTML
اﻟﺘ
Manipuler une page HTML depuis un programme JavaScript
ﺤﻤﻴ
Introduction aux concepts d'API et d’événements
ﻞﻣ
Plan du chapitre:
ﻦﻣ
1. JavaScript et le DOM (Slides du TP)
Application: Calculatrice
ﻮﻗﻊ
ﺗﻌﻠ
Références:
ﻢ
JavaScript Kit (en Anglais, moins à jour, mais plus concis et avec des exemples plus
ﻣﺠ
simples)
ﻪﻣ
Aide-mémoires:
ﻦا
ﻟﺒﺪ
JavaScript/DOM)
اﻹ
ﺣﱰ
اف
1. JavaScript et le DOM
Dans les chapitres précédents, nous avons exécuté des programmes JavaScript simples de
manière interactive, depuis la console de notre navigateur.
ﺗﻢ
depuis une page web au format HTML.
Navigateur Web / Web Browser: c'est un logiciel d'affichage de pages web
ا
ﻟﺘﺤ
(généralement composées de fichiers HTML, CSS et JavaScript), et permettant à
ﻤﻴﻞ
l'utilisateur d’interagir avec celles-ci.
DOM: Document Object Model, c'est à la fois le nom qu'on donne à l'ensemble des
ﻣﻦ
éléments qui constituent une page Web ouverte dans le navigateur (telle qu'elle est
ﻣﻮﻗ
structurée en mémoire), et à l'API qui permet de manipuler ces éléments.
ﻊﺗ
API: Application Programming Interface, est un ensemble de fonctions fournies par un
logiciel (par exemple: un navigateur Web, ou un serveur Web) qui permettent à d'autres
ﻌﻠﻢ
Vous devez savoir qu'une page web peut être associée à une feuille de style CSS. Pour
ﻦا
cela, le code source HTML de cette page doit contenir un élément <link> donnant l'URL du
ﻟﺒﺪ
De la même façon, pour associer un programme JavaScript à une page web, il suffit
إﱃ
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<h1>Bonjour !</h1>
<script src="script.js"></script>
</body>
</html>
l'élément <script> peut être défini dans le <head> ou dans le <body> , mais il est
généralement recommandé de l'insérer juste avant la fin du <body> ;
l'URL du script doit être fournie via l'attribut src ;
mais surtout, contrairement aux éléments <link> , les éléments <script> ne doivent
pas être exprimés sous forme d'une balise auto-fermante (finissant par /> ) => il est
impératif d'utiliser une balise fermante </script> après chaque balise ouvrante
<script> .
Les scripts ainsi intégrés dans le <body> de la page seront exécutés au fur et à mesure
ﺗ
ﻢا
qu'ils sont découverts et chargés par le navigateur.
ﻟﺘﺤ
Remarque, il est aussi possible d'intégrer directement notre programme JavaScript
ﻤﻴﻞ
entre les balises <script> et </script> , pour éviter de le stocker dans un fichier
séparé. Cette méthode n'est pas recommandée car elle peut causer des erreurs de
ﻣﻦ
syntaxe.
ﻣ
Application: Dire bonjour au monde
ﺗ ﻮﻗﻊ
ﻌﻠﻢ
Vous allez créer une page web qui affiche Bonjour le monde ! dans une fenêtre à l'aide de
la fonction alert() .
اﻟﱪ
ﻣﺠ
Pour cela:
ﻪ
1. Créez un fichier bonjour.html définissant une page web minimale mais valide,
ﻣﻦ
2. Ouvrez cette page dans votre navigateur, pour vérifier qu'elle s'affiche correctement.
ﺪ
اﻳﻪ
<script> .
اف
Les navigateurs Web (tels que Google Chrome) donnent accès à une API (voir définition
plus haut) permettant à nos programmes JavaScript d'interagir avec le DOM de la page Web
à laquelle ils sont liés.
C'est à dire qu'un script intégré dans une page peut utiliser des fonctions permettant de
manipuler le contenu de cette page. Par exemple: pour récupérer des informations saisies
par l'utilisateur dans des champs de la page, ou encore modifier le contenu et/ou l'affichage
de la page.
Pour accéder à un élément de la page, il faut identifier précisément (c.a.d. sans ambiguïté)
cet élément auprès du navigateur. Par exemple: en l'adressant par son identifiant unique
ﺗﻢ
(attribut id de l'élément).
اﻟﺘ
Pour cela, l'API du DOM met à notre disposition un objet (cf chapitre précédent) appelé
ﺤﻤﻴ
document , et cet objet contient plusieurs fonctions. Nous allons d'abord nous intéresser à la
ﻞﻣ
fonction getElementById() qui permet d'accéder à l'objet représentant un élément de la
ﻦﻣ
page, en fonction de son identifiant unique.
ﻮﻗﻊ
Supposons que notre page Web contienne les éléments suivants:
ﺗ
ﻌﻠﻢ
<body>
<p id="premier-paragraphe">Bonjour</p>
<p id="deuxieme-paragraphe">le monde</p>
اﻟ
ﱪﻣ
</body>
ﺠﻪ
Nous pouvons alors accéder au premier paragraphe en JavaScript (ex: depuis un script
ﻣﻦ
document.getElementById('premier-paragraphe');
// => retourne un objet qui représente l'élément HTML correspondant
إﱃ
اﻹ
En exécutant cet appel de fonction dans la console, on voit s'afficher ce qu'elle retourne: un
ﺣﱰ
identifiant.
Nous allons voir plus bas que l'objet document fourni par l'API du DOM contient d'autre
fonctions permettant d'accéder à des éléments, comme getElementsByClassName() ou
encore querySelector() .
Application:
1. allez sur le site web de votre choix,
2. utilisez l'onglet "Éléments" de Chrome Dev Tools (barre latérale dans laquelle se trouve
Astuce: pour accéder plus rapidement à la partie du DOM qui représente un élément
d'une page Web, effectuer un clic-droit sur cet élément de la page, puis cliquez sur
"Inspecter". Vous vous retrouverez immédiatement dans l'onglet "Éléments" de la page,
à l'endroit où est défini cet élément.
ﺗﻢ
اﻟﺘ
Maintenant que nous savons accéder à l'objet JavaScript correspondant à un élément HTML
ﺤﻤﻴ
de la page, nous allons voir comment récupérer des données de cet élément.
ﻞﻣ
Pour cela, nous allons utiliser la propriété value de l'objet JavaScript représentant un
ﻦﻣ
élément HTML.
<form>
اﻟﱪ
<label for="nom">Nom:</label>
ﻣﺠ
</form>
</body>
ﺪ اﻟﺒ
اﻳﻪ
Pour accéder à l'objet JavaScript représentant le champ portant l'identifiant nom , nous
إﱃ
document.getElementById('nom');
اف
Enfin, pour récupérer la valeur actuelle de ce champ, il suffit d'utiliser la propriété value de
cet objet:
document.getElementById('nom').value;
ﺗﻢ
tel que définis dans l'exemple ci-dessus (avec identifiants nom et prenom );
ا
ﻟﺘﺤ
3. Toujours dans ce dossier, créer un fichier index.js contenant un programme
ﻤﻴﻞ
JavaScript qui affichera avec alert() la valeur du premier champ de la page, puis
celle du deuxième champ;
ﻣﻦ
4. Associez votre programme JavaScript (fichier index.js ) à votre page HTML (fichier
index.html ), de manière à ce qu'il soit exécuté quand on ouvre la page, et vérifier que
ﻣﻮﻗ
les deux valeurs sont bien affichées dans des alert lors du chargement de la page
ﻊﺗ
dans votre navigateur;
ﻌﻠﻢ
5. En cas de malfonctionnement, corrigez les erreurs dans vos fichiers, en vous aidant de
la console JavaScript.
اﻟﱪ
ﻣﺠ
Maintenant que nous savons accéder aux données d'une page HTML depuis un programme
اﻳﻪ
allons voir comment exécuter des instructions JavaScript en réponse à une action de
l'utilisateur sur la page.
اﻹ
ﺣﱰ
À chaque fois que l'utilisateur interagit avec une page Web, le navigateur déclenche des
اف
événements. Ces événements sont mis à disposition par l'API du DOM, afin qu'un
programme JavaScript puisse les intercepter et réagir à certains d'entre eux.
On peut définir le comportement (la réaction) que doit adopter le navigateur lorsqu'un
événement survient, en y associant une fonction JavaScript.
Pour l'instant, nous allons employer la méthode la plus simple: affecter une fonction à la
propriété d'un élément correspondante à l'événement choisi.
ﺗﻢ
اﻟﺘ
Imaginons une page HTML contenant un bouton:
ﺤﻤﻴ
<body>
ﻞﻣ
<button id="mon-bouton">Mon Beau Bouton</button>
ﻦﻣ
</body>
ﻮﻗﻊ
Pour afficher un alert à chaque fois que l'utilisateur cliquera sur ce bouton (événement
ﺗﻌﻠ
click ), nous devons affecter une fonction à la propriété onclick de l'objet JavaScript
représentant ce bouton:
ﻢ اﻟ
ﱪﻣ
alert('bonjour !');
};
ﻣﻦا
ﻟﺒﺪ
Exercice: Calculatrice
اﻳﻪ
lorsque l'utilisateur clique, nous allons développer une calculatrice simple en HTML +
اﻹ
JavaScript.
ﺣﱰ
اف
deux champs <input> portant les valeurs d' id : " premier-nombre " et " deuxieme-
nombre ";
Ensuite, y associer un fichier JavaScript qui permettra à l'utilisateur, à chaque fois qu'il
cliquera sur le bouton mon-bouton , d'obtenir le résultat de l'addition des nombres qu'il aura
saisis dans les champs premier-nombre et deuxieme-nombre , dans le champ resultat .
ﺗ
soustraction, multiplication et division.
ﻢا
ﻟﺘﺤ
ﻤﻴﻞ
ﻣﻦ
ﻣﻮﻗ
ﻊﺗ
ﻌﻠﻢ
اﻟﱪ
ﻣﺠ
ﻪﻣ
ﻦا
ﻟﺒﺪ
اﻳﻪ
إﱃ
اﻹ
ﺣﱰ
اف
ﺗﻢ
Objectifs:
اﻟﺘ
ﺤﻤﻴ
Utiliser JavaScript pour manipuler le contenu et l'apparence de pages Web
Développer une liste avec filtrage dynamique par catégorie
ﻞﻣ
Comprendre la portée des variables en JavaScript
ﻦﻣ
Plan du chapitre:
5. Manipulation d'attributs
اﻳﻪ
Exemple:
Dans cet exemple, l'élément <p> est associé à une classe hidden . Pour que tous les
éléments associés à cette classe soient cachés, il suffirait alors de définir la règle CSS
suivante:
.hidden {
display: none;
}
ﺗ
ﻢا
ﻟﺘﺤ
Exemple:
ﻤﻴﻞ
var element = document.getElementById('un-element');
element.classList.add('hidden'); // => la classe hidden va être associée à l'élément
ﻣﻦ
Exercice: Afficher/cacher ﻣﻮﻗ
ﻊﺗ
ﻌﻠﻢ
Créer une page web valide contenant les deux paragraphes <p> tels que définis plus
haut.
اﻟﱪ
Y associer un fichier CSS contenant la règle .hidden tel que définie plus haut.
ﻣﺠ
Quel code JavaScript faut-il exécuter pour retirer la classe hidden du deuxième
ﻣﻦ
paragraphe ?
اﻟﺒ
Solution: Codepen
ﺪ
اﻳﻪ
إﱃ
اﻹ
Dans la partie précédente, nous avons utilisé la fonction getElementById() pour accéder à
un des éléments de notre page, à partir de son identifiant id .
L'API du DOM donne également accès à une fonction qui permet d'accéder à l'ensemble
des éléments qui portent une même classe class : getElementsByClassName() .
Supposons que nous soyons sur une page HTML contenant plusieurs paragraphes portant
une même classe:
Pour accéder à tous les éléments portant la classe spoiler , nous allons utiliser le code
JavaScript suivant:
ﺗ
ﻢا
élément, mais un tableau de plusieurs éléments.
ﻟﺘﺤ
Pour effectuer une même manipulation sur chacun des éléments de ce tableau, il suffit
ﻤﻴﻞ
d'utiliser une boucle for , tel que nous l'avons vu dans un précédent chapitre.
ﻣﻦ
Exercice: Cacher les spoilers
ﻣﻮﻗ
Créer une page web valide contenant les trois paragraphes <p> tels que définis dans
ﻊﺗ
l'exemple ci-dessus.
ﻌﻠﻢ
Y associer un fichier CSS contenant la règle .hidden tel que définie plus haut.
اﻟﱪ
Ajouter un bouton à la page HTML, et y intégrer le code JS nécessaire pour que les
ﻦا
spoilers soient cachés seulement une fois que l'utilisateur aura cliqué sur le bouton.
ﻟﺒﺪ
Attention, aucun code JavaScript ne doit pas apparaître dans votre fichier HTML =>
اﻳﻪ
Solution: Codepen
اﻹ
ﺣﱰ
اف
Dans cette partie, nous allons voir qu'il est possible de modifier dynamiquement le style
d'éléments HTML sans avoir à manipuler de classes CSS.
De la même manière que les éléments HTML <input> fournissent une propriété JavaScript
value permettant d'accéder à leur valeur, tous les éléments HTML fournissent une
Alors que la propriété value est de type String (chaîne de caractères), la propriété
style est de type Object .
L'objet associé à la propriété style est structuré similairement à une règle CSS: il est
constitué de propriétés clé-valeur.
ﺗ
ﻢا
#mon-element {
ﻟﺘﺤ
border: 1 solid black;
background-color: red;
ﻤﻴﻞ
}
ﻣﻦ
... et l'objet JavaScript correspondant, tel qu'associé à la propriété style de l'élément:
ﻣﻮﻗ
ﻊﺗ
{
border: '1 solid black',
ﻌﻠﻢ
backgroundColor: 'red'
}
اﻟﱪ
ﻣﺠ
donc les valeurs de propriétés sont des chaînes de caractères (entre apostrophes), et
ﻟﺒﺪ
les propriétés doivent être séparées par des virgules (au lieu des point-virgules de la
اﻳﻪ
notation CSS);
إﱃ
enfin, les noms de propriétés contenant des tirets doivent être écris en respectant la
اﻹ
notation "camel case" (pour rappel: mots collés, avec majuscules en début de chaque
ﺣﱰ
Pour modifier la couleur de fond du premier paragraphe, il faut exécuter le code JavaScript
suivant:
ﺗﻢ
Bonus: Intégrer le code JavaScript nécessaire pour que la couleur de fond de n'importe
اﻟﺘ
quel paragraphe de la page devienne jaune quand l'utilisateur clique dessus. (indice: il
ﺤﻤﻴ
va falloir utiliser le paramètre fourni à l'appel de votre fonction onclick , nous ne
ﻞﻣ
l'avons pas encore vu en cours)
ﻦﻣ
Solution: Codepen (et bonus)
ﻮﻗﻊ
Exercice à rendre: Filtrage par catégorie
ﻢ ﺗﻌﻠ
Vous allez développer une page web contenant une liste de produits, et permettant à
اﻟﱪ
l'utilisateur de filtrer l'affichage de ces produits, en activant les catégories de produits qui
ﻣﺠ
l'intéressent.
ﻪ
Vous êtes libre sur le choix des produits et des catégories qui seront proposés sur votre
page, sur leur rendu visuel, ainsi que sur la manière d'activer les catégories.
Contraintes à respecter:
ﺗ
ﻢا
<article class="ludique pratique">iPad</article>
ﻟﺘﺤ
<article class="ludique sportif">Batte de baseball</article>
<article class="pratique">Ventilateur</article>
ﻤﻴﻞ
ﻣﻦ
Vous serez évalué(e) selon les critères suivants:
Solution: Codepen
ﻣﺠ
ﻪ
ﻣﻦ
اﻟﺒ
Dans certains cas, il est pratique d'adresser les éléments par type (nom de balise). C'est ce
que permet la fonction getElementsByTagName() .
Exemple:
5. Manipulation d'attributs
Fonctions DOM: getAttribute() et setAttribute()
Nous avons vu qu'il était possible de récupérer et/ou modifier la valeur d'un champ <input>
ﺗﻢ
à l'aide de la propriété value de l'objet JavaScript représentant ce champ.
ا
ﻟﺘﺤ
Il se trouve que value est aussi le nom de l'attribut HTML correspondant. En effet, le DOM
ﻤﻴﻞ
donne accès à des propriétés correspondant aux attributs standards des éléments HTML.
ﻣﻦ
<button id="mon-bouton" data-numero="5">
ﻣﻮﻗ
ﻊﺗ
ﻌﻠﻢ
L'attribut data-numero n'est pas standard, mais nous avons le droit de nous en servir pour
rattacher des informations à cet élément.
اﻟ
ﱪﻣ
suivante:
ﻣﻦ
document.getElementById('mon-bouton').getAttribute('data-numero');
ا
ﻟﺒﺪ
suivante:
اﻹ
ﺣﱰ
document.getElementById('mon-bouton').setAttribute('data-numero', 7);
اف
Avant que nous décrivions comment modifier la structure du DOM d'une page web, sachez
qu'il est possible de modifier directement depuis JavaScript le code HTML contenu par un
élément HTML: à l'aide de la propriété innerHTML de cet élément.
Exemple:
ﺗﻢ
اﻟﺘ
Cette affectation modifiera le DOM de la page web de la manière suivante:
ﺤﻤﻴ
<!-- Après: -->
ﻞﻣ
<p id="mon-parag">image: <img src="image.jpg"></p>
ﻦﻣ
ﺗ ﻮﻗﻊ
7. Scope et génération de fonctions
اﻟ ﻌﻠﻢ
Nous avons vu plus haut qu'il fallait utiliser une boucle for pour effectuer une même
ﱪﻣ
Exemple:
ﻣﻦ
اﻟﺒ
elements[i].classList.add('bordure-rouge');
إﱃ
}
اﻹ
ﺣﱰ
Par contre, dès qu'une boucle for définit une fonction qui sera appelée plus tard et dépend
de la variable de boucle, notre programme se comporte de manière inattendue...
C'est notamment le cas si on définit une fonction onclick dans une boucle, tel que dans
l'exemple suivant:
En cliquant sur les éléments sur lesquels s'applique cette boucle, vous constaterez que
l' alert affichera toujours le même élément, alors que la variable de boucle i prend bien
comme valeur l'indice de chaque élément de la page.
ﺗﻢ
Ce comportement est dû à la manière dont JavaScript référence les variables: leur "portée"
اﻟﺘ
(appelée "scope", en Anglais).
ﺤ
ﻤﻴﻞ
"Scope": portée des variables
ﻣﻦ
En JavaScript, toute variable définie par var est rattachée à la fonction qui contient
sa définition, ou dans l'espace "global" sinon.
ﻣﻮﻗ
ﻊﺗ
Illustration:
ﻌﻠﻢ
var variableGlobale = 4;
اﻟﱪ
function maFonction() {
ﻣﺠ
var variableLocale = 5;
console.log('(maFonction) variableGlobale:', variableGlobale); // => 4
ﻪ
}
maFonction();
اﻟﺒ
is not defined
ﱃ
اﻹ
d'abord chercher s'il existe une variable localement définie, puis chercher dans les contextes
اف
parents dans lesquels ont été définis cette fonction, jusqu'à l'espace global, si besoin.
Dans le cas de notre boucle for (cf exemple plus haut), la fonction affectée à la propriété
onclick utilise la variable i , et cette variable n'est pas locale à cette fonction: elle est
Du coup, lorsque cette fonction est appelée (en l’occurrence: au moment où l'utilisateur
clique sur un élément), c'est la valeur de cette variable au moment de l'appel qui va être
utilisée. Or, au moment de l'appel, notre boucle a fini d'itérer, et la variable i vaut donc sa
valeur maximum. (en l’occurrence: elements.length )
Pour éviter ce problème de portée, le plus simple est d'appeler à chaque itération une
fonction en passant notre variable i en paramètre, de manière à ce que sa valeur soit
rattachée à la fonction (comme si c'était une variable locale), et non au contexte parent.
Dans les deux cas, cette fonction devra retourner une autre fonction, de manière à ce que
cette dernière ne soit pas appelée immédiatement au moment de la définition de la fonction
parente.
ﺗﻢ
اﻟﺘ
Fonction génératrice de fonction
ﺤﻤﻴ
ﻞﻣ
Nous avons vu qu'une fonction pouvait retourner une valeur de n'importe quel type, et que
les fonctions étaient un des types avancés du langage JavaScript. Il est donc tout à fait
ﻦﻣ
possible qu'une fonction retourne une autre fonction !
Exemple:
ﻮﻗﻊ
ﻢ ﺗﻌﻠ
function mere() {
اﻟﱪ
};
}
ﻦا
var fct = mere(); // => affiche 'fonction mere appelée' puis retourne la fonction fille
ﻟﺒﺪ
Pour éviter le problème de portée expliqué plus haut, il suffit alors de passer la valeur en
ﺣﱰ
function mere(i) {
// i est *promue* comme variable locale à la fonction mere
// => à chaque appel de la fonction qu'elle retourne, elle aura conservé sa valeur
return function fille() {
alert('vous avez cliqué sur l\'élément nº' + i);
// i fait référence à la valeur qui avait été passée en paramètre
// de l'appel à la fonction mere(), à chaque itération de boucle.
};
}
// supposons que elements soit un tableau d'éléments HTML
for (var i = 0; i < elements.length; i++) {
elements[i].onclick = mere(i);
// => la fonction retournée par mere va être affecté à fille
ﺗﻢ
}
اﻟﺘ
ﺤﻤﻴ
ﻞﻣ
ﻦﻣ
ﺗ ﻮﻗﻊ
اﻟ ﻌﻠﻢ
ﱪﻣ
ﺠﻪ
ﻣﻦ
ﺪاﻟﺒ
اﻳﻪ
إﱃ
اﻹ
ﺣﱰ
اف
ﺗﻢ
Développer un composant web simple
اﻟﺘ
Permettre à un même composant d'être instancié plusieurs fois sur une même page
ﺤﻤﻴ
Initiation à la Programmation Orientée Objet et au mot clé this
ﻞﻣ
Plan du chapitre:
ﻦﻣ
1. Création d'un composant Web simple (Slides du TP)
ﻮﻗﻊ
Exercice: Accordéon / Carousel / Galerie vidéo
2. Composant Web multi-instances et POO (Slides du TP)
ﺗﻌﻠ
Défi: Plusieurs instances de Carousel sur une même page
ﻢ اﻟ
Sur le Web, un composant est un programme qui permet de fournir une interface intégrable,
إﱃ
Les composants permettent donc d'enrichir le contenu, l’esthétique, et/ou les interactions
proposées par un site Web, en ré-utilisant du code qui n'a pas été écrit spécifiquement pour
ce site.
Il existe de très nombreux composants publiés sur Internet et utilisables gratuitement. Pour
la plupart, ils sont basés sur la librairie "jQuery" (dont nous parlerons plus tard dans ce
cours). Mais nombreux ont été conçus en JavaScript/DOM natif (aussi appelé "Vanilla
JavaScript"), et peuvent donc fonctionner sans jQuery.
Note: Dans le cadre de ce cours, l'usage (direct ou pas) de jQuery ne sera pas
accepté.
Sweet Alert
Dialog Modal
Animate on scroll
Tranglify
Vous pourrez trouver d'autres composants natifs sur le site Vanilla List.
ﺗﻢ
À ce stade, nous allons apprendre à réaliser un composant simple, dans le sens où celui-ci
اﻟﺘ
ne sera pas suffisamment modulaire pour être intégré plusieurs fois sur une même page.
ﺤﻤﻴ
Nous verrons plus tard comment faire cela.
ﻞﻣ
Généricité et instructions d'intégration
ﻦﻣ
ﻮﻗﻊ
Afin que notre composant puisse être intégré de manière personnalisée par chaque
développeur, quelque soit le site Web en question et son contenu, il est important de définir
ﺗﻌﻠ
quelques règles et abstractions.
ﻢ
jamais avoir à consulter ni modifier le code source du composant. Il va falloir donc que le
ﻣﺠ
composant soit suffisamment générique et configurable depuis le site Web qui l’intégrera.
ﻪﻣ
Par exemple, un composant de galerie d'images doit s'adapter à une liste d'images fournie
ﻦا
ne doit pas contenir de valeurs et références littérales; (ex: nombre d'images et/ou
ﺣﱰ
doit définir et documenter les règles et contraintes éventuelles que devront respecter
les intégrateurs du composant.
toutes les images à afficher dans la galerie doivent être des balises <img> portant la
classe carousel-img ;
ou encore: appeler la fonction creerGallerie() (définie par le composant) en passant en
paramètres l'identifiant du DIV devant contenir la galerie, et un tableau d'URLS
d'images.
Prenez le temps d'analyser les instructions d'intégration des composants listés plus haut.
une description concise du composant: à quoi il sert, quelles sont ses fonctionnalités et
avantages éventuels;
une démonstration du composant, pour le tester depuis la page;
ﺗﻢ
les instructions permettant d'intégrer simplement ce composant à son site;
اﻟﺘ
la description des fonctions et/ou paramètres éventuellement fournis par le composant;
ﺤﻤﻴ
BONUS: la liste des navigateurs (et leur versions) sur lesquels le composant
fonctionne;
ﻞﻣ
BONUS: le composant et sa documentation publiés sur GitHub.
ﻦﻣ
S'inspirer de la documentation des composants fournis plus haut en exemple.
ﻮﻗﻊ
Conseil pratique: pour afficher du code source sur une page HTML sans que celui-ci ne
ﺗﻌﻠ
soit interprété par le navigateur, utiliser la balise <xmp> .
ﻢ
اﻟﱪ
Composant: Carousel
ﻣﺠ
ﻪﻣ
Certains carousels passent automatiquement d'une image à l'autre, à l'aide d'un minuteur
( setTimeout() ou setInterval() ).
Solution: Jsfiddle
Composant: Accordéon
Un "accordéon" est un composant proposant plusieurs rubriques à l'utilisateur, et lui
ﺗﻢ
permettant d'afficher le contenu d'une rubrique à la fois, en cliquant sur son titre.
ا
ﻟﺘﺤ
ﻤﻴﻞ
ﻣﻦ
ﻣﻮﻗ
ﻊﺗ
ﻌﻠﻢ
اﻟﱪ
ﻪ ﻣﺠ
ﻣﻦ
getElementsByTagName() ),
إﱃ
et la gestion du scope.
اف
Solution: Jsfiddle
ﺗﻢ
اﻟﺘ
ﺤﻤﻴ
Pour développer une galerie vidéo, il faut maîtriser:
ﻞﻣ
les sélecteurs DOM ( getElementById() , getElementsByClassName() et/ou
getElementsByTagName() ),
ﻦﻣ
la capture d'événements onclick ,
ﻮﻗﻊ
l'intégration d' <iframe> (ex: à l'aide de innerHTML ),
et la gestion du scope.
ﺗ
ﻌﻠﻢ
Solution: Jsfiddle
اﻟ
ﱪﻣ
ﺠﻪ
Dans la partie précédente, vous avez appris à développer un composant Web simple.
اﻹ
Mais votre composant fonctionnera-t-il correctement si vous l'intégrez plusieurs fois sur une
ﺣﱰ
Supposons par exemple que vous ayez développé un composant de Carousel permettant
de créer une galerie d'images à partir des éléments <img> de la page portant la classe
carousel-img (comme celui-ci). Si vous souhaitez intégrer deux galeries indépendantes sur
votre page, avec des images spécifiques à chacune d'elles, le composant ne sera pas
capable de faire la distinction entre les images de ces deux galeries, car il se contente de
créer une galerie à partir de toutes les images portant la classe carousel-img !
Alors, comment faire pour qu'un composant puisse être intégré plusieurs fois sur une même
page ?
ﺗ
ﻢا
Solution 1: Composant qui s'applique sur des groupes
ﻟﺘﺤ
d'éléments
ﻤﻴﻞ
Supposons que notre composant à intégrer fournisse les instructions d'intégration suivantes:
ﻣﻦ
ﻣﻮﻗ
Au chargement du composant, chaque élément portant la classe image-group sera
transformé en Carousel, à partir des balises <img> définis dans cet élément.
ﻊﺗ
ﻌﻠﻢ
Galerie 1:
ﻣﺠ
<div class="image-group">
<img src="img1.jpg">
ﻪﻣ
<img src="img2.jpg">
ﻦا
<img src="img3.jpg">
</div>
ﻟﺒﺪ
Galerie 2:
اﻳﻪ
<div class="image-group">
<img src="img4.jpg">
إﱃ
<img src="img5.jpg">
<img src="img6.jpg">
اﻹ
</div>
ﺣﱰ
Pour fonctionner ainsi, le code source du Carousel devra récupérer les images de chaque
groupe, de la manière suivante:
ﺗﻢ
Remarque: Ici, nous avons appelé la fonction getElementsByTagName() sur un élément,
اﻟﺘ
et non sur document . Ceci a pour effet de ne retourner que les éléments qui sont
ﺤﻤﻴ
contenus à l'intérieur de cet élément parent.
ﻞﻣ
Avantages de cette solution:
ﻦﻣ
simple à implémenter, à documenter et à intégrer.
d'éléments
ﻦا
ﻟﺒﺪ
اﻳﻪ
إﱃ
اﻹ
ﺣﱰ
اف
Par exemple, comment regénérer une galerie après l'ajout d'une image ?
Pour permettre ce genre de manipulation, il faudrait que chaque galerie soit accessible
individuellement depuis le code JavaScript de l'intégrateur.
ﺗﻢ
maGalerie2.ajouterImage('img7.jpg');
اﻟﺘ
maGalerie2.regenerer();
ﺤﻤﻴ
ﻞﻣ
Pour cela, il faudrait que chaque galerie puisse être référencée par une variable, et donc
que le composant fournisse un moyen de retourner une variable pour chaque galerie créée.
ﻦﻣ
La solution consiste à ce que le code source du composant définisse une fonction pour
ﻮﻗﻊ
créer une galerie et retourner une référence vers un objet permettant à l'intégrateur
ﺗﻌﻠ
d'interagir avec cette galerie.
ﻢ
Exemple:
اﻟﱪ
ﻣﺠ
}
conteneur.innerHTML == html;
إﱃ
return reference;
}
اف
urlImages un tableau contenant les URLs des images à intégrer dans la galerie. Cette
Comment définir cet objet reference qui permettra à l'intégrateur d'interagir distinctement
ﺗ
ﻢا
avec chaque galerie ? En définissant puis instanciant une classe, tel que nous allons le voir
ﻟﺘﺤ
ensuite.
ﻤﻴﻞ
Programmation Orientée Objet: classes, instances et
ﻣﻦ
this
ﻣﻮﻗ
Une classe est un modèle d'objet. Elle peut être instanciée, c'est à dire qu'on crée un objet
ﻊﺗ
(appelé instance) selon ce modèle.
ﻌﻠﻢ
La modèle d'une classe consiste à assurer que chaque objet instance de cette classe aura
اﻟﱪ
les mêmes:
ﻣﺠ
À noter que:
ﻟﺒﺪ
اﻳﻪ
chaque instance d'une classe aura les mêmes propriétés, mais la valeur de celles-ci
pourra être différente pour chaque instance;
إﱃ
chaque instance d'une classe aura les mêmes méthodes, mais l'exécution de la
اﻹ
fonction correspondante ne s'appliquera qu'à l'instance sur laquelle elle aura été
ﺣﱰ
appelée.
اف
Exemple de classe que vous avez déjà utilisée sans le savoir: la classe Element .
En effet, à chaque fois que vous appelez la fonction document.getElementById() , elle vous
retourne un objet qui est en fait une instance de la classe Element . C'est grâce à la classe
Element que vous pouvez utiliser les propriétés value , onclick et la méthode
Notez que getElementById() est aussi une méthode. Quand on effectue un appel à
document.getElementById() , on exécute en réalité la méthode getElementById() sur l'objet
Afin de permettre l'appel des méthodes ajouterImage() et regenerer() sur une instance
de Galerie :
ﺗﻢ
maGalerie2.ajouterImage('img7.jpg');
maGalerie2.regenerer();
اﻟﺘ
ﺤﻤﻴ
... notre composant Carousel doit définir la classe Galerie de la manière suivante:
ﻞﻣ
ﻦﻣ
class Galerie {
}
اﻟﱪ
ﻣﺠ
this.urlImages.push(url);
ﻦا
}
ﻟﺒﺪ
regenerer() {
var html = '';
إﱃ
}
اف
this.conteneur.innerHTML == html;
}
le code que nous avions écrit dans la fonction creerGalerie() se trouve maintenant
dans la définition de la méthode regenerer() de notre classe Galerie ;
les paramètres conteneur et urlImages de la fonction creerGalerie() ont été
transférés au constructeur de la classe Galerie , et stockées sous forme de propriétés
Maintenant que la classe Galerie de notre composant est définie, il va falloir que notre
fonction creerGalerie() retourne une instance de cette classe.
ﺗﻢ
// ...pour que l'intégrateur puisse avoir accès aux méthodes ajouterImage() et regen
erer()
اﻟﺘ
}
ﺤﻤﻴ
ﻞﻣ
Le mot clé new permet d'instancier notre classe, et donc d'exécuter son constructeur (défini
plus haut) en leur transmettant les paramètres conteneur et urlImages . La variable
ﻦﻣ
reference contient alors une instance de cette classe, et permet donc d'appeler les
ﻮﻗﻊ
méthodes regenerer() et ajouterImage() sur cette instance.
ﺗﻌﻠ
Usage de this
ﻢ
اﻟﱪ
Quand on mentionne this dans la définition d'une méthode, ce mot clé représente
ﻣﺠ
Par exemple:
ﻦا
ﻟﺒﺪ
class Article {
اﻳﻪ
constructor(titre) {
this.titre = titre;
إﱃ
}
اﻹ
getTitre() {
ﺣﱰ
À noter qu'en JavaScript, this est en fait utilisable depuis toute fonction, qu'elle soit ou pas
définie dans une classe. Il faut retenir que l'usage de classes permet à l'interpréteur
JavaScript d'affecter automatiquement à this l'instance sur laquelle s'exécute chaque
méthode.
Attention: pour cette dernière raison, il est parfois nécessaire de garder une référence de
this , en particulier quand on souhaite y accéder depuis une sous-fonction.
Exemple:
class Galerie {
// [...]
ﺗﻢ
// [...]
// génération des éléments <img> dans le conteneur
اﻟﺘ
var galerie = this;
ﺤ
for (var i = 0; i < this.urlImages.length; i++) {
ﻤﻴﻞ
img.onclick = function() {
galerie.afficherImageSuivante(); // car dans cette fonction, this !== galerie
ﻣﻦ
};
}
// [...]
} ﻣﻮﻗ
ﻊﺗ
ﻌﻠﻢ
}
اﻟﱪ
Dans l'exemple ci-dessus, nous souhaitons appeler une méthode de notre instance de
ﻣﺠ
galerie, quand l'utilisateur cliquera sur n'importe laquelle des images affichée par la galerie.
ﻪ
Pour cela, nous devons définir et affecter une fonction anonyme à l'attribut onclick de
ﻣﻦ
chaque image, définissant le comportement que devra adopter le navigateur à chaque clic.
اﻟﺒ
classe Galerie sur laquelle a été appelée la méthode regenerer , mais à l'objet sur lequel a
ﻪإ
été appelé la fonction anonyme. Pour conserver une référence vers notre instance, nous
ﱃ
avons affecté la valeur de this à une variable galerie , en dehors de la définition de notre
اﻹ
fonction anonyme.
ﺣﱰ
اف
par le composant. (ex: ajouter une image, dans le cas d'un composant Carousel)
Pour que le code JavaScript de votre composant soit intégrable sans que l'utilisateur ait
besoin de dupliquer votre code source dans celui de son site, vous pouvez publier le fichier
.js correspondant sur votre espace étudiant, ou sur Codepen. (le code JS sera alors
ﺗﻢ
accessible directement en ajoutant l'extension .js à votre URL Codepen, ex:
اﻟﺘ
http://codepen.io/adrienjoly/pen/ggNNba.js )
ﺤﻤﻴ
Vous serez évalués sur:
ﻞﻣ
ﻦﻣ
la concision et clarté des instructions d'intégration fournies sur la page de
documentation de votre composant;
ﻮﻗﻊ
la simplicité effective d'intégration du composant;
la qualité d'une ou plusieurs démos directement utilisables sur la page de
ﺗﻌﻠ
documentation de votre composant;
ﻢ اﻟ
site.
ﺠﻪ
--> http://marijnhaverbeke.nl/talks/es6_falsyvalues2015/exercises/#Point
إﱃ
اﻹ
ﺣﱰ
اف
ﺗ
ﻢا
Objectifs:
ﻟﺘﺤ
Inspecter la source d'un évènement du DOM
ﻤﻴﻞ
Manipuler la structure du DOM en JavaScript
ﻣﻦ
Plan du chapitre:
utilisé l'API fournie par le navigateur pour accéder aux éléments du DOM d'une page
web/HTML,
اﻹ
ﺣﱰ
comment en savoir plus sur un évènement qui a été déclanché par l'utilisateur,
comment naviguer dans le DOM d'une page web/HTML, de noeud en noeud,
et comment en modifier la structure.
Pour afficher un alert à chaque fois que l'utilisateur cliquera sur ce bouton, nous avons vu
qu'il fallait affecter une fonction à la propriété onclick de l'objet JavaScript représentant ce
bouton:
ﺗ
ﻢا
document.getElementById('mon-bouton').onclick = function() {
ﻟﺘﺤ
alert('bonjour !');
};
ﻤﻴﻞ
ﻣﻦ
En effet, les propriétés d'évènements ( onclick , onchange , ou autre) d'un élément
permettent d'indiquer au navigateur quelle fonction appeler lorsque l'évènement
correspondant est déclenché par l'utilisateur.
ﻣﻮﻗ
ﻊﺗ
Ce que nous n'avons pas encore vu, en revanche, c'est que le navigateur passe
ﻌﻠﻢ
Event .
ﻣﺠ
document.getElementById('mon-bouton').onclick = function(event) {
ﻟﺒﺪ
console.log(event);
اﻳﻪ
};
إﱃ
valeur l'élément HTML sur lequel l'évènement a été intercepté par notre fonction.
اف
Cette propriété est particulièrement utile dans le cas où nous voulons affecter une même
fonction de gestion d'évènement sur plusieurs éléments, mais que cette fonction a besoin de
savoir sur lequel de ces éléments l'évènement a été déclenché.
Par exemple:
À noter que, selon le type d'évènement auquel est associée une fonction, le paramètre
event peut être une instance de sous-classes contenant des propriétés et méthodes
supplémentaires.
ﺗ
ﻢا
Par exemple:
ﻟﺘﺤ
le paramètre event d'une fonction liée à l'évènement mousemouse (appelée à chaque
ﻤﻴﻞ
mouvement de la souris) est une instance de la classe `MouseEvent' qui possède les
ﻣﻦ
propriétés clientX et clientY , afin de connaître la position de la souris sur l'écran.
le paramètre event d'une fonction liée à l'évènement keydown (appelée quand
ﻣﻮﻗ
l'utilisateur tape un caractère dans un champ) est une instance de la classe
ﻊﺗ
KeyboardEvent qui possède les propriétés key et keyCode , permettant de connaître
ﻌﻠﻢ
preventDefault() qui permet d'annuler le traitement habituel d'un évènement qui a été
intercepté par une fonction. Cette méthode est par exemple utile pour empêcher l'ouverture
ﻪﻣ
d'un hyperlien <a> , la soumission d'un formulaire, ou l'ajout de caractères dans un champ.
ﻦا
ﻟﺒﺪ
Créer une page HTML simple contenant un champ <input> dont la valeur est effacée
quand l'utilisateur presse la touche "Entrée".
اﻹ
ﺣﱰ
Solution: jsfiddle
اف
<body>
<button id="mon-bouton">Mon Beau Bouton</button>
</body>
Dans cette page, l'élément <button> a l'élément <body> comme parent, et un noeud texte
(le contenu textuel de l'élément) comme enfant. On peut aussi dire que <button> est un
noeud enfant de <body> .
Ici, le seul enfant de notre élément <button> est un noeud textuel, mais il serait possible
que ce même élément ait d'autres éléments comme enfants.
ﺗﻢ
Supposons que notre bouton soit référencé par la variable element :
ا
ﻟﺘﺤ
var element = document.getElementById('mon-bouton');
ﻤﻴﻞ
ﻣﻦ
Comme tout élément HTML représenté en JavaScript (et donc instance de la classe
Element ), notre variable element possède trois propriétés utiles pour nous aider à
childNodes est un tableau de noeuds HTML (éléments et/ou noeuds textuels), enfants
ﻣﺠ
directs de l'élément.
ﻪﻣ
page)
اﻳﻪ
element.children est un tableau vide, car il n'y a pas d'éléments à l'intérieur du bouton,
إﱃ
et
اﻹ
element.childNotes est un tableau qui ne contient que le noeud textuel ayant pour
ﺣﱰ
Écrire le code JavaScript permettant de colorier le fond du <div> parent en jaune lorsqu'un
bouton est cliqué par l'utilisateur.
ﺗﻢ
اﻟﺘ
Pour cela, utiliser une boucle for , une seule fonction onclick , son paramètre event , les
ﺤﻤﻴ
propriétés parentNode et style .
ﻞﻣ
Solution: jsfiddle
ﻦﻣ
ﻮﻗﻊ
3. Modification de la structure du DOM
ﻢ ﺗﻌﻠ
اﻟﱪ
À ce stade, nous savons accéder à des éléments du DOM, modifier leur contenu et rendu,
et accéder à leurs parent et enfants.
ﻣﺠ
ﻪ
Dans cette partie, nous allons voir comment créer, rattacher et supprimer des noeuds du
ﻣﻦ
DOM.
ﺪ اﻟﺒ
Pour ajouter un élément HTML dans le DOM d'une page web, le navigateur fournit les
اﻹ
méthodes suivantes:
ﺣﱰ
élément.
Donc, pour ajouter un bouton au <body> d'une page HTML, il faudra exécuter les
instructions JavaScript suivantes;
// 1. créer l'élément
var bouton = document.createElement('button');
// 2. créer le contenu du bouton (noeud textuel)
var texteDuBouton = document.createTextNode('Mon beau bouton');
// 3. ajouter le contenu au bouton
bouton.appendChild(texteDuBouton);
// 4. ajouter le bouton au body de la page
document.body.appendChild(bouton);
ﺗ
ﻢا
Le retrait d'un noeud du DOM est l'opération inverse de celle d'ajout ( appendChild() ): elle
ﻟﺘﺤ
consiste à appeler la méthode conteneur.removeChild(noeud) , où conteneur est le noeud
parent duquel on souhaîte retirer noeud .
ﻤﻴﻞ
Ainsi, pour supprimer le bouton que nous avons ajouté à la page de l'exemple précédent, il
ﻣﻦ
faudra exécuter:
document.body.removeChild(bouton); ﻣﻮﻗ
ﻊﺗ
ﻌﻠﻢ
bouton.parentNode.removeChild(bouton);
ﻣﺠ
ﻪﻣ
ﻦا
En partant d'une page HTML vierge, développer le code JavaScript permettant d'ajouter à la
اﻳﻪ
page:
إﱃ
un champ <input> ,
اﻹ
Solution: jsfiddle
Solution: jsfiddle
ﺗﻢ
اﻟﺘ
ﺤﻤﻴ
ﻞﻣ
ﻦﻣ
ﻮﻗﻊ
ﻢﺗﻌﻠ
اﻟﱪ
ﻣ
ﺠﻪ
ﻣﻦ
اﻟﺒ
ﺪاﻳ
ﱃ ﻪإ
اﻹ
ﺣﱰ
اف
ﺗﻢ
Objectifs:
اﻟﺘ
ﺤﻤﻴ
Interroger une API du Web en JavaScript
Envoyer des informations à une API du Web
ﻞﻣ
Plan du chapitre:
ﻦﻣ
1. Effectuer une requête GET avec XMLHttpRequest (Slides du TP)
ﻮﻗﻊ
Exercice: afficher la météo de la ville de l'utilisateur
ﺗ
2. Effectuer une requête POST avec XMLHttpRequest (Slides du TP)
ﻌﻠﻢ
XMLHttpRequest
ﺪاﻟﺒ
اﻳﻪ
Introduction
إﱃ
Créé en 1995, le procédé AJAX (Asynchronous Javascript and XML) a été intégré aux
اﻹ
ﺣﱰ
Une requête AJAX consiste à effectuer une requête HTTP depuis du code JavaScript.
Pour rappel, HTTP est le protocole employé par les navigateurs pour communiquer avec les
serveurs Web.
Par exemple, quand nous allons sur Google, nous tapons http://google.com dans la barre
du navigateur, ce qui a pour effet de demander la page HTML de recherche au serveur
HTTP de google.com . Ceci est une requête de type GET , car elle permet seulement de
récupérer des données depuis ce serveur, contrairement aux requêtes POST permettant
d'envoyer des données à un serveur.
A noter que le chargement d'une page HTML déclanche généralement d'autres requêtes
HTTP, afin de récupérer toutes les ressources associées à cette page Web: scripts, feuilles
de style CSS, images, etc...
ﺗﻢ
اﻟﺘ
ﺤﻤﻴ
ﻞﻣ
ﻦﻣ
ﻮﻗﻊ
ﺗﻌﻠ
ﻢ اﻟ
ﱪﻣ
ﺠﻪ
ﻣﻦا
ﻟﺒﺪ
Formats de données
اﻳﻪ
Par exemple:
ﺣﱰ
Nous allons nous intéresser en particulier aux formats représentant des données
structurées.
Initialement, AJAX a été créé pour récupérer des données au format XML. Un format proche
du HTML, et très en vogue à l'époque.
<inbox>
<email from="amazon">votre colis a été envoyé</email>
</inbox>
Désormais, la majorité des sites Web emploient le format JSON pour échanger des données
structurées.
ﺗﻢ
اﻟﺘ
{
ﺤﻤﻴ
"email": {
"from": "amazon",
ﻞﻣ
"subject": "votre colis a été envoyé"
}
ﻦﻣ
}
ﻮﻗﻊ
Pour rappel, JSON (JavaScript Object Notation) est en fait la syntaxe utilisé pour définir des
ﺗ
ﻌﻠﻢ
objets en JavaScript.
اﻟ
En supposant que cet objet JSON soit stocké dans une variable objet , le langage
ﱪﻣ
JavaScript nous permet d'accéder facilement aux données qui y sont stockées.
ﺠﻪ
Par exemple, pour afficher la valeur de la propriété subject de la propriété email , il suffit
ﻣﻦ
de saisir:
ﺪاﻟﺒ
console.log(objet.email.subject);
اﻳﻪ
إﱃ
Pour récupérer des données depuis une URL HTTP, le navigateur met à notre disposition la
اف
classe XMLHttpRequest . Malgré son nom, il est possible de l'utiliser pour récupérer des
données exprimées dans d'autres formats que XML.
ﺗ
qu'il a été téléchargé intégralement.
ﻢا
ﻟﺘﺤ
Effectuer une requête avec XMLHttpRequest consiste en 4 étapes:
ﻤﻴﻞ
1. instancier la classe, avec new ;
2. spécifier la méthode ( GET ) et l'URL du document à récupérer, en appelant la méthode
ﻣﻦ
open() ;
ﻣ
ﻮﻗﻊ
3. définir ce qu'on souhaite faire de la réponse, une fois reçue intégralement, en affectant
une fonction à la propriété onreadystatechange de notre instance;
ﺗ
ﻌﻠﻢ
4. puis envoyer la requête, en appelant la méthode send() de notre instance.
responseText .
ﺪ اﻟﺒ
À noter que, même si le document en question est au format JSON (par exemple),
اﻳﻪ
responseText contiendra la version sérialisée du document, c'est à dire qu'il sera de type
إﱃ
string , et non object . À ce stade, il n'est donc pas possible d'accéder à une propriété
اﻹ
Nous allons voir comment convertir cette chaîne de caractères en veritable objet dans la
اف
prochaine partie.
Cette fonction prend en paramètre une chaîne de caractères (type: string ) contenant la
version sérialisée d'un objet, et retourne l'objet correspondant (type: object ).
Comme cet objet est sérialisé sous forme de chaine de caractères, il n'est pas possible
d'accéder directement à ses propriétés.
ﺗﻢ
Pour permettre cela, nous le passer en paramètre de la fonction JSON.parse() :
ا
ﻟﺘﺤ
var chaine = '{"message":"bonjour!"}';
ﻤﻴﻞ
var objet = JSON.parse(chaine);
console.log(objet.message); // => "bonjour!"
ﻣﻦ
ﻣﻮﻗ
Donc, pour récupérer un objet JavaScript depuis la réponse JSON de notre requête AJAX, il
faut utiliser le code suivant:
ﻊﺗ
ﻌﻠﻢ
xhr.onreadystatechange = function() {
ﻣﺠ
if (xhr.readyState === 4) {
var reponse = JSON.parse(xhr.responseText);
ﻪﻣ
alert(reponse.name);
ﻦا
}
};
ﻟﺒﺪ
xhr.send();
اﻳﻪ
إﱃ
Bien entendu, n'oubliez pas de remplacer l'URL de cet exemple par celle à laquelle se
trouve le document que vous souhaitez récupérer !
اﻹ
ﺣﱰ
N'oubliez pas non plus de consulter la console de votre navigateur ainsi que la partie
اف
"Réseau" (ou "Network", en anglais) de Chrome Dev Tools, afin de diagnostiquer les
éventuelles erreurs.
Animations: Giphy
Photos: Flickr
Météo: openweathermap (doc) (HTTP Only)
Chatons: puppygifs.tumblr.com/api/read/json (JSON var with CORS)
ﺗﻢ
créez un compte développeur sur le site de l'API, si besoin,
اﻟﺘ
lisez les parties suivantes pour intégrer l'éventuelle clé API dans l'URL de votre
ﺤﻤﻴ
requête AJAX.
ﻞﻣ
Exercice 1: Récupérer l'adresse IP de l'utilisateur
ﻦﻣ
ﻮﻗﻊ
Effectuer une requête AJAX vers l'API httpbin.org/ip qui affichera seulement l'heure fournie
en réponse dans un alert() .
ﺗﻌﻠ
Solution: ajax-get-ip.js.
ﻢ
اﻟﱪ
Réaliser une page Web permettant d'afficher la météo d'une ville saisie par l'utilisateur. Pour
ﻣﻦ
Etapes:
ﻪ
2. ajouter un code JavaScript qui affiche le contenu du champ quand on clique sur le
اﻹ
bouton.
ﺣﱰ
4. faire en sorte que l'appel AJAX s'adapte en fonction de la saisie, à chaque clic sur le
bouton.
Solution: ajax-get-weather.html.
Les images doivent être affichées directement dans la page à l'aide d'éléments <img> ,
après la saisie de l'utilisateur. Pour cela, vous pouvez utiliser innerHTML , ou les méthodes
présentées dans le chapitre sur la manipulation avancée du DOM.
ﺗ
Pour des raisons de sécurité, les navigateurs empêchent le protocole HTTP d'être employé
ﻢا
depuis une page Web affichée via HTTPS. Cette contrainte a des implications importantes
ﻟﺘﺤ
sur le fonctionnement des requêtes AJAX.
ﻤﻴﻞ
Notamment:
ﻣﻦ
Une page ouverte en HTTPS (ex: jsfiddle) ne peut pas effectuer de requête AJAX vers
ﻣ
ﻮﻗﻊ
des URLs HTTP (non sécurisée), seulement vers des URLs HTTPS.
Si vous exécutez une requête AJAX depuis la console d'une page HTTPS, les mêmes
ﺗﻌﻠ
constraintes s'appliquent.
ﻢ
Donc, dans la mesure du possible, assurez-vous d'utiliser le protocole HTTPS dans l'URL
اﻟﱪ
Restrictions de domaines
ﻦا
ﻟﺒﺪ
En plus des restrictions de sécurité HTTPS, certaines APIs ne permettent pas l'exécution de
اﻳﻪ
D'autres refusent carrément de répondre aux requêtes émises depuis d'autres domaines
اﻹ
que le leur.
ﺣﱰ
Dans ce cas, vous pourrez seulement exécuter des requêtes AJAX depuis une page de leur
اف
Exemple:
https://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=74a9b070d210
72ccac3a7b5f44f09efa&tags=soccer&format=json&nojsoncallback=1
Comme dans la définition de propriétés d'un objet JavaScript, chaque paramètre est
composé d'un nom (aussi appelé clé) et d'une valeur. Dans une URL, le nom et la valeur de
chaque paramètre sont séparés par un = .
ﺗ
ﻢا
le paramètre nommé tags vaut soccer ,
ﻟﺘﺤ
le paramètre nommé format vaut json ,
ﻤﻴﻞ
et le paramètre nommé nojsoncallback vaut 1 .
De le cas où vous voudriez passer la valeur d'une variable de votre programme JavaScript
ﻣﻦ
en paramètre de votre URL, vous pouvez utiliser la concaténation.
ﻣ
Exemple:
ﻮﻗﻊ
ﺗﻌﻠ
var tags = 'soccer';
ﻢ
Attention: Ceci fonctionne bien quand la valeur de votre variable ne contient aucun caractère
ﻪﻣ
spécial. Par contre que se passerait-il si elle contenait un espace, ou un & ? L'URL
ﻦ اﻟ
Pour éviter que les caractères spéciaux éventuels d'une chaine de caractères ne puisse
ﻪإ
Exemple:
http://api.openweathermap.org/data/2.5/weather?q=London,uk&appid=44db6a862fba0b067b193
0da0d769e98
Pour obtenir une clé, rendez-vous sur le site Web de cette API, puis intégrez la clé fournie
dans l'URL de votre/vos requête(s) AJAX.
ﺗﻢ
اﻟﺘ
Dans la partie précédente, nous avons utilisé la classe XMLHttpRequest pour envoyer des
ﺤ
ﻤﻴﻞ
requêtes de type HTTP GET . Pour rappel, ce type de requête permet de récupérer des
informations depuis un serveur.
ﻣﻦ
Dans cette partie, nous allons voir comment utiliser cette même classe pour envoyer des
ﻣﻮﻗ
requêtes de type HTTP POST . Même s'il permet aussi de recevoir une réponse du serveur à
ﻊﺗ
ces requêtes, ce type de requête permet d'envoyer des informations.
ﻌﻠﻢ
xhr.onreadystatechange = function() {
ﺪاﻳ
if (xhr.readyState === 4) {
ﻪإ
alert(xhr.responseText);
}
ﱃ
};
اﻹ
Le principe de fonctionnement est exactement le même que celui d'une requête GET , sauf
que nous avons cette fois-ci envoyé une chaine de caractères via notre requête à
l'adresse serveur https://httpbin.org/post .
Pour envoyer un objet JavaScript / JSON dans une requête POST , il faut d'abord sérialiser
l'objet (c'est à dire: le convertir) sous forme de chaine de caractères, à l'aide de la fonction
JSON.stringify() .
Il suffit donc de modifier le paramètre passé à la méthode send() , tel que dans l'exemple
suivant:
ا ﺗﻢ
alors que JSON.parse() permet de convertir une chaine de caractères en objet,
ﻟﺘﺤ
JSON.stringify() permet de convertir un objet en chaine de caractères.
ﻤﻴﻞ
Attention: veillez à ne pas appeler la méthode send() d'une même instance (ex:
ﻣﻦ
xhr , dans notre exemple) plus d'une seule fois !
vérifier la présence éventuelle d'erreurs dans votre code et/ou dans vos requêtes AJAX.
ﻣﺠ
Utilisez l'onglet "Réseau" (ou Network, en anglais) de Chrome Dev Tools pour suivre
ﻣﻦ
serveur.
ﺪ
اﻳﻪ
Le but de cet exercice est de publier vos messages en utilisant une requête AJAX.
Sont fournis:
une page web affichant en temps réél le flux des derniers messages publiés sur le
serveur;
une API HTTP permettant de publier des messages sur le serveur, accessible depuis
l'adresse /tweet ;
et un client simple permettant de publier des messages à l'aide d'un formulaire HTML.
L'objet JSON à envoyer comme contenu de la requête doit contenir deux propriétés:
ﺗ
message : le texte à publier. (type: string )
ﻢا
token : le jeton fourni après identification de l'utilisateur. (type: string )
ﻟﺘﺤ
ﻤﻴﻞ
Note: La valeur de la propriété token de l'objet à envoyer est générée automatiquement
par le client simple fourni, dans la variable globale window.token .
ﻣﻦ
À chaque requête HTTP valide reçue, le serveur répondra par un objet JSON ayant:
ﻣﻮﻗ
soit une propriété error contenant un message d'erreur (type: string );
ﻊﺗ
soit une propriété ok , dans le cas où le message a été publié sans erreur.
ﻌﻠﻢ
Remarque importante: le bouton d'identification de Google n'a été activé que depuis les
اﻟﱪ
exécuter le client simple fourni (ni une version dérivée) depuis un autre domaine, ni
ﻪﻣ
Étapes proposées
ﻟﺒﺪ
اﻳﻪ
3. Remplacer le formulaire par l'envoi d'une requête HTTP POST à chaque fois que
ﺣﱰ
Bonus: améliorations
Quand vous aurez terminé toutes les étapes proposées ci-dessus, vous pourrez apporter les
améliorations suivantes à votre client:
Solution: jsbin
ا ﺗﻢ
ﻟﺘﺤ
ﻤﻴﻞ
ﻣﻦ
ﻣﻮﻗ
ﻊﺗ
اﻟ ﻌﻠﻢ
ﱪﻣ
ﺠﻪ
ﻣﻦا
ﻟﺒﺪ
اﻳﻪ
إﱃ
اﻹ
ﺣﱰ
اف
ﺗﻢ
Objectifs:
اﻟﺘ
ﺤﻤﻴ
Intégrer un bouton de connexion pour identifier l'utilisateur
Gérer l'état de l'application en fonction de l'identification
ﻞﻣ
(Slides du TP)
ﻦﻣ
ﻮﻗﻊ
ﺗﻌﻠ
Introduction
ﻢ
اﻟﱪ
Sur la plupart des sites, cette identification est matérialisée par trois opérations:
اﻹ
ﺣﱰ
ا ﺗﻢ
ﻟﺘﺤ
ﻤﻴﻞ
ﻣﻦ
ﻣﻮﻗ
ﻊﺗ
Le mécanisme le plus répandu est OAuth. Il standardise les échanges nécessaires entre la
ﻌﻠﻢ
plateforme tierce d'identification et une application, afin que cette dernière puisse accéder
اﻟ
Dans ce cours, nous n'allons pas décrire le fonctionnement de OAuth, mais en récapituler
les grandes lignes.
ﻣﻦا
ﻟﺒﺪ
Voici ce qui est affiché à l'utilisateur, après qu'il ait cliqué sur un bouton "Se connecter avec
إﱃ
ا ﺗﻢ
ﻟﺘﺤ
ﻤﻴﻞ
ﻣ ﻣﻦ
Cette page web est générée par Facebook pour demander à l'utilisateur s'il accepte de
ﻮﻗﻊ
partager ses données d'identification avec l'application depuis laquelle il a cliqué sur le
ﺗﻌﻠ
bouton.
ﻢ اﻟ
Le plus souvent, ces données contiennent notamment le nom de l'utilisateur, son adresse
ﱪﻣ
Du point de vue du développeur d'une application, l'identification des utilisateurs via une
إﱃ
ﺗﻢ
اﻟﺘ
ﺤﻤﻴ
ﻞﻣ
ﻦﻣ
1. L'application s'identifie auprès de la plateforme, à l'aide d'un identifiant souvent appelé
APP_ID , CLIENT_ID ou API_KEY .
ﺗ ﻮﻗﻊ
2. La plateforme vérifie la validité de cet identifiant, et sa concordance avec le nom de
ﻌﻠﻢ
5. La plateforme prend note des préférences de vie privée de l'utilisateur, pour cette
ﻦا
application.
ﻟﺒﺪ
6. Enfin, elle contacte l'application pour l'informer de l'accord de l'utilisateur, et lui transmet
اﻳﻪ
un jeton (en anglais: token ), une chaine de caractères que devra utiliser l'application
إﱃ
pour communiquer désormais avec la plateforme. Par exemple: pour accéder aux
informations personnelles de l'utilisateur.
اﻹ
ﺣﱰ
اف
Mise en oeuvre
Dans la plupart des cas, le développeur d'application peut gagner beaucoup de temps en
utilisant un bibliothèque (en anglais: library) ou un SDK (Software Development Kit) fourni
par la plateforme.
Il existe de nombreux guides sur Internet comment utiliser ces outils, pour les applications
Web et Mobile.
Dans notre cas, nous allons utiliser le SDK Google Platform Library depuis notre application
Web JavaScript.
ا ﺗﻢ
ﻟﺘﺤ
Note importante: la clé CLIENT_ID fournie dans le code ne fonctionne que depuis le
site jsbin.com . Vous ne pourrez donc pas utiliser ce code pour identifier des
ﻤﻴﻞ
utilisateurs depuis un autre domaine, ni depuis votre propre machine.
ﻣﻦ
Solution: jsbin.com/tuyofec
Maintenant que nous savons intégrer un bouton Google Signin à une application, nous
allons créer notre propre clé CLIENT_ID , de manière à ce que notre application puisse
اﻟﱪ
Pour cela, vous allez devoir déclarer votre propre application auprès de Google et configurer
ﻦا
Étapes proposées:
اﻳﻪ
1. Héberger le code précédent sur votre espace étudiant, observer l'erreur obtenue
إﱃ
3. Créer un projet, et moyen de s'identifier à l'application Web avec "OAuth" depuis votre
ﺣﱰ
domaine
اف
4. Intégrer la clé CLIENT_ID fournie dans votre page, puis tester la connexion et
déconnexion.
5. BONUS: restreindre l'accès qu'à certaines personnes.
6. BONUS: Refaire l'exercice avec Facebook Connect au lieu de Google Signin.
autres références:
ا ﺗﻢ
ﻟﺘﺤ
ﻤﻴﻞ
ﻣ ﻣﻦ
ﻮﻗﻊ
ﺗﻌﻠ
ﻢ اﻟ
ﱪﻣ
ﺠﻪ
ﻣﻦ
ﺪاﻟﺒ
اﻳﻪ
إﱃ
اﻹ
ﺣﱰ
اف
ﺗﻢ
Comprendre les bases d'usage de la bibliothèque jQuery
ا
ﻟﺘﺤ
Découvrir Node.js et l'installation de modules avec npm
ﻤﻴﻞ
Découvrir la création d'une Single Page App avec Augular et React
ﻣﻦ
Convertir un composant jQuery en
JavaScript/DOM pur ﻣﻮﻗ
ﻊﺗ
ﻌﻠﻢ
Références:
ﻣﺠ
Plain JS
ﻦا
ﻟﺒﺪ
Solution: jsfiddle
Node.js et npm
Introduction
En début d'année, nous avons vu qu'il existait différents types d'interpréteurs JavaScript.
Exemples:
ﺗﻢ
la console de Chrome permet d'exécuter des instructions JavaScript de manière
اﻟﺘ
interactive.
ﺤﻤﻴ
un fichier JavaScript intégré dans une page web est exécuté dès l'ouverture de cette
page dans un navigateur.
ﻞﻣ
Il existe un autre moyen d'exécuter du code JavaScript: Node.js.
ﻦﻣ
ﻮﻗﻊ
Node.js est un logiciel basé sur le moteur d'exécution intégré dans Google Chrome: V8. Il
est constitué de deux commandes exécutables depuis le "terminal" (la console du système
ﺗﻌﻠ
d'exploitation): node et npm .
ﻢ اﻟ
La commande node permet d'exécuter du code JavaScript, alors que npm permet de
ﱪﻣ
télécharger puis installer des modules (appelés packages) de manière locale (dans le
ﺠﻪ
dossier en cours) ou globale (=> modules accessibles depuis n'importe quel dossier).
ﻣﻦ
Node.js est couramment utilisé pour développer des serveurs web (aussi appelé back-end,
ا
dans le cas de développement d'applications client-serveur telles que les applications web),
ﻟﺒﺪ
mais permet aussi la réalisation de scripts ayant accès à toutes les fonctions du système
اﻳﻪ
d'exploitation: système de fichiers, accès illimité aux ressources de n'importe quel réseau
إﱃ
npm est couramment utilisé pour installer les dépendances, c'est à dire les modules
ﺣﱰ
sous Windows, appuyer sur la touche "Windows", taper "cmd" puis presser
ENTRÉE.
sous Mac, presser Cmd-Espace, taper "term" puis presser ENTRÉE.
Si la commande node n'est pas trouvée par le système, il faudra installer Node.js
depuis son site officiel, puis ré-ouvrir le terminal avant de poursuivre la manipulation.
Une fois Node.js lancé, vous pouvez taper des instructions, comme dans la console de
Chrome Dev Tools.
ﺗﻢ
Par exemple: tapez 1+1; pour voir le nombre 2 s'afficher en retour.
اﻟﺘ
Pour quitter l'interpréteur Node.js, pressez Ctrl-C.
ﺤﻤﻴ
ﻞﻣ
Exécuter un fichier .js avec Node.js
ﻦﻣ
ﻮﻗﻊ
Nous allons d'abord créer un fichier test.js très simple, en tapant la commande suivante
dans le terminal:
ﺗ
ﻌﻠﻢ
Ensuite, pour exécuter ce fichier, il suffit alors de taper la commande suivante depuis le
terminal:
ﺪاﻟﺒ
اﻳﻪ
node test.js
إﱃ
اﻹ
bonjour
À noter que les symboles tels que window , document , alert() et getElementById()
ne sont pas définis par Node.js, car ils sont seulement fournis lorsqu'un programme
JavaScript s'exécute depuis un navigateur Web !
ﺗﻢ
Single Page Apps avec Augular et React
ا
ﻟﺘﺤ
ﻤﻴﻞ
Front-end VS back-end
ﻣﻦ
ﻣﻮﻗ
Une application Web moderne consiste en: ﻊﺗ
un client / front-end: programme exécuté par le navigateur de chaque utilisateur,
ﻌﻠﻢ
et un "serveur web" / back-end: programme exécuté sur une machine appelée
"serveur", qui a pour mission de répondre aux requête des "clients" (et donc de chaque
اﻟﱪ
utilisateur).
ﻣﺠ
Comme nous l'avons vu, un client "web" est généralement constitué de fichiers HTML, CSS
ﻪﻣ
et JavaScript ayant accès à l'API du DOM fournie par le navigateur. À moins qu'il utilise des
ﻦا
moyens de persister ses données (ex: à l'aide de cookies, LocalStorage, ou requêtes AJAX
ﻟﺒﺪ
vers un serveur), son "état" (c.a.d. toutes les données de l'utilisateur saisies dans la page, et
اﻳﻪ
Un "serveur web" est rattaché à une adresse IP (ex: 127.0.0.1 , ou nom de domaine) et un
اﻹ
port (ex: 80 ), et permet de réagir et répondre à des requêtes HTTP envoyées par des
ﺣﱰ
"clients" à différents chemins (ex: /posts ) et avec différentes méthodes (ex: GET , POST ,
اف
etc...). Un "serveur web" peut être implémenté en nombreux langages: PHP, Java, ASP,
etc... Node.js peut être utilisé pour exécuter un serveur web implémenté en JavaScript.
Il est relativement facile et rapide de développer un client web simple: il suffit d'une page
HTML associée à un fichier JavaScript.
Par contre, dès qu'une application web contient plusieurs écrans et/ou modes (ex: utilisateur
connecté ou pas), elle devient vite complexe à écrire et maintenir.
Notamment, pour aider au développement de clients web, les technologies suivantes sont
actuellement très en vogue:
ﺗﻢ
Suivez les guides liés à ces deux technologies pour comprendre leur fonctionnement par la
اﻟﺘ
pratique.
ﺤﻤﻴ
ﻞﻣ
Solutions hybrides
ﻦﻣ
Il existe aussi des bibliothèques et frameworks permettant de faciliter le lien entre front-end
ﻮﻗﻊ
et back-end:
ﺗ
ﻌﻠﻢ
Firebase permet de créer une base de données sur internet, et d'y accéder directement
depuis un client web, et se présente donc comme une alternative simple à un serveur
اﻟﱪ
web / back-end. Solution valable quand le plus gros de son application s'exécute dans
ﻣﺠ
le navigateur. (consulter slides et vidéos de mon cours de l'an dernier et/ou guide
ﻪﻣ
officiel)
ﻦا
Basé sur Node.js et MongoDB, Meteor permet de créer des applications web JavaScript
ﻟﺒﺪ
isomorphiques. C'est à dire que des parties du code peuvent s'exécuter à la fois côté
اﻳﻪ
serveur et/ou côté client (dans le navigateur). Un de ses gros avantages est de
إﱃ
Ces deux solutions sont très pratiques pour réaliser des prototypes de manière rapide /
efficace.
ﺗ
ﻢا
Objectifs:
ﻟﺘﺤ
Prévoir un intercepter les cas d'erreurs
ﻤﻴﻞ
Application: détecter la position géographique de l'utilisateur
ﻣﻦ
Consulter les slides du TP.
ﻣ
Références: ﻮﻗﻊ
Error Handling in Node.js
ﺗﻌﻠ
Utiliser la Géolocalisation
ﻢ
Dans un programme informatique comme dans la vie, tout ne se passe pas toujours comme
إﱃ
prévu !
اﻹ
ﺣﱰ
Dans ce chapitre, nous allons découvrir les différents types d'erreurs qui peuvent survenir
dans un programme JavaScript, et comment les gérer dans notre code.
اف
Une instruction synchrone est dite "bloquante". C'est à dire que l'instruction suivante sera
exécutée seulement une fois que l'opération invoquée par cette instruction aura fini de
s’exécuter.
Exemple:
Une instruction asynchrone est dite "non bloquante". C'est à dire qu'elle d’éclanche une
opération qui va se dérouler en arrière plan, pendant que les instructions suivantes du
ﺗ
programme vont être exécutées.
ﻢا
ﻟﺘﺤ
Conséquence importante: le résultat de l’exécution d'une instruction asynchrone n'était pas
ﻤﻴﻞ
disponible immédiatement, il va falloir définir et fournir un fonction qui sera appelée à la fin
de l'opération asynchrone correspondante.
ﻣﻦ
Exemple:
ﻣ
function direBonjour() {
ﺗ ﻮﻗﻊ
console.log('bonjour !');
ﻌﻠﻢ
}
setTimeout(direBonjour, 1000);
اﻟﱪ
console.log('salut !');
ﻣﺠ
// => salut va s'afficher avant bonjour, car setTimeout() est une fonction asynchrone.
ﻪﻣ
Généralement, une instruction asynchrone consiste à appeler une fonction, en passant une
ﻦا
autre fonction de callback en paramètre. Cette fonction de callback sera appelée à la fin de
ﻟﺒﺪ
Le résultat passé en paramètre de la fonction de callback peut être une valeur résultante de
إﱃ
synchrone) ou une description de l'erreur qui serait éventuellement survenue pendant cette
ﺣﱰ
synchrone)
Synchrone Asynchrone
Erreur de programmation immédiate Erreur de programmation tardive
Erreur opérationnelle gérable par Erreur opérationnelle gérable par fonction de
try - catch callback
Erreurs de programmation
ﺗﻢ
Les erreurs de programmation sont causées par le développeur du programme. Souvent par
ا
inattention, ou cas non prévus.
ﻟﺘﺤ
ﻤﻴﻞ
Exemples d'erreurs de programmation:
ﻣﻦ
usage d'un symbole non défini: variable ou instruction mal orthographiée
ﻣﻮﻗ
usage d'une propriété ou méthode d'un objet non défini ( undefined )
ﻊﺗ
non respect du type d'un paramètre de fonction
ﻌﻠﻢ
fonction de callback non passée en paramètre de l'appel d'une fonction asynchrone
Quand une erreur survient dans un programme JavaScript s’exécutant dans un navigateur
اﻟﱪ
web, ce dernier arrête l’exécution de ce programme et affiche l'erreur dans la console, afin
ﻣﺠ
Les erreurs de ce type peuvent être corrigées en relisant attentivement le code (ex: localiser
ﻦا
cas limites (ex: que se passe-t-il si l'utilisateur clique sur le bouton "annuler" au lieu de
اﻳﻪ
Erreurs opérationnelles
ﺣﱰ
اف
Une erreur opérationnelle n'est pas directement causée par le développeur du programme.
Elle peut survenir dans des cas en dehors de son contrôle.
le serveur auquel une requête AJAX a été envoyée met trop de temps à répondre
le paramètre passé à JSON.parse() n'est pas un objet JSON valide
le navigateur de l'utilisateur a empêché le pop-up de s'ouvrir
ﺗﻢ
indirectement causée: synchrone ou asynchrone.
ا
ﻟﺘﺤ
Cas synchrone
ﻤﻴﻞ
Dans le cas d'une opération synchrone, il suffit de contenir l'instruction pouvant causer une
ﻣﻦ
erreur à l’intérieur d'un bloc try - catch .
ﻣﻮﻗ
Par exemple, la fonction JSON.parse() est synchrone, et déclanchera une erreur si la
ﻊﺗ
chaîne de caractères passée en paramètre n'est pas une chaine de caractère ou si elle ne
ﻌﻠﻢ
contient pas du JSON valide. Pour gérer cette erreur dans notre programme:
اﻟﱪ
try {
ﻣﺠ
var json = JSON.parse('{ JSON invalide }'); // cause une erreur interceptée par le c
ﻪ
atch()
ﻣﻦ
}
اﻳﻪ
Cas asynchrone
ﺣﱰ
اف
Par contre, il est important de gérer ce type d'erreurs quand même afin d'en informer
l'utilisateur, et éventuellement l'aider à trouver une solution afin de ne pas rester bloqué.
Pour rappel, quand on déclenche une opération asynchrone, il faut généralement fournir une
fonction de callback en paramètre de la fonction correspondante. La gestion d'erreur se fait
alors en analysant la valeur d'un des paramètres passés à l'appel de cette fonction de
callback.
Dans les programmes Node.js, c'est le premier paramètre d'une fonction de callback qui est
conventionnellement réservé à cet usage, et contient soit une instance de la classe Error ,
soit la valeur null ou undefined (dans le cas où aucune erreur n'aurait eu lieu).
uneFonctionAsynchrone(function(err, res) {
if (err) {
ﺗ
ﻢا
alert('une erreur est survenue: ' + err.message);
} else {
ﻟﺘﺤ
alert('resultat de la fonction: ' + res);
ﻤﻴﻞ
}
});
ﻣﻦ
Mais les conventions dépendent de la fonction qui est appelée. Par exemple, la fonction
ﻣﻮﻗ
getCurrentPosition() de l'API Geolocation prend deux fonctions de callback: une première
ﻊﺗ
qui sera appelée quand la position de l'utilisateur sera déterminée, et une deuxième qui ne
ﻌﻠﻢ
function traiterPos(pos) {
ﻣﺠ
function traiterErr(err) {
ﻣﻦ
navigator.geolocation.getCurrentPosition(traiterPos, traiterErr);
إﱃ
À noter que certaines opérations asynchrones proposent une manière spécifique de gérer
اﻹ
ﺣﱰ
les erreurs. Par exemple, la classe XMLHttpRequest demande au développeur d'affecter une
fonction à la propriété onerror de l'instance correspondante à une requête AJAX.
اف
Il faut donc toujours penser à lire la documentation des fonctions et classes qu'on utilise
dans son programme, afin de gérer les erreurs éventuelles.
1. L'application informe l'utilisateur qu'il devra donner son autorisation pour accéder à la
position géographique
2. L'application va alors appeler l'API de positionnement pour tenter de détecter la position
de l'utilisateur
ﺗﻢ
Si la position est bien détectée, afficher les coordonnées sur la page
ا
ﻟﺘﺤ
Si la position n'est pas détectée (erreur asynchrone), afficher l'erreur
ﻤﻴﻞ
correspondante sur la page
Enfin, si l'API n'est pas accessible (erreur synchrone), afficher le message API
ﻣﻦ
Geolocation non disponible .
ﻣﻮﻗ
3. Dans le cas où le position a été détectée, l'application va déterminer l'adresse postale
correspondante à ces coordonnées
ﻊﺗ
Si une adresse est détectée, l'afficher sur la page, en plus des coordonnées
ﻌﻠﻢ
Si l'adresse n'est pas reconnue, afficher adresse non reconnue sur la page
Si une autre erreur est survenue lors de l'appel à l'API, afficher le message d'erreur
اﻟﱪ
BONUS: En plus d'afficher les coordonnées et adresse postale où se trouve l'utilise (ou
ﻟﺒﺪ
ﺗﻢ
اﻟﺘ
ﺤﻤﻴ
ﻞﻣ
ﻦﻣ
ﻮﻗﻊ
ﻢ ﺗﻌﻠ
اﻟﱪ
ﻣ
ﺠﻪ
ﻣﻦ
اﻟﺒ
ﺪاﻳ
ﱃ ﻪإ
اﻹ
ﺣﱰ
اف