addEventListener
) ;Javascript autorise la création de fonctions anonymes :
function (param1, param2) { /* instructions here */ }
Contrairement à une déclaration de fonction, une fonction anonyme peut apparaître partout ou une fonction est acceptée.
C'est utile dans les cas ou cette fonction n'a pas vocation à être réutilisée ailleurs, en particulier pour les abonnements à des événements.
Exemple :
let b = document.querySelector("button");
b.addEventListener('click', function() {
let i = document.getElementsByTagName("input")[0];
i.value = Number(i.value) + 1;
});
En ES6, il existe une syntaxe plus compacte pour les fonctions anonymes. Au lieu d'écrire :
function (x, y) { return x+y; }
on peut utiliser la notation :
(x, y) => { return x+y; }
Dans le cas où la fonction comporte une unique instruction return
,
on peut même remplacer le corps de la fonction par l'expression à retourner :
(x, y) => x+y
Dans le cas où la fonction comporte exactement un argument, on peut ommettre les parenthèses autour de l'argument :
x => { console.log(x); return x+1; }
Autres exemples :
x => x+1
() => {
console.log("Fonction flêche sans argument,");
console.log("et comportant plusieurs instructions.");
}
Adaptation de l'exemple précédent :
let b = document.querySelector("button");
b.addEventListener('click', () => {
let i = document.getElementsByTagName("input")[0];
i.value = Number(i.value) + 1;
});
Note
Les fonctions "flêches" ne sont pas absolument équivalentes aux fonctions anonymes, mais la distinction concerne des notions non abordées dans ce chapitre.
Pour en savoir plus : https://stackoverflow.com/a/34361380
Les variables déclarées hors de toute fonction,
même préfixées par let
,
sont considérées par Javascript comme des variables globales.
Afin de contourner ce problème, il existe en Javascript une convention : on "enferme" tout le code du script dans une fonction anonyme, que l'on appelle immédiatement :
(function() {
// ... mon code Javascript ici ...
})();
Ainsi, on évite de polluer l'environnement global.
let b1 = document.querySelector('button#b1');
b1.addEventListener("click", () => {
let previousContent = b1.textContent;
b1.textContent = "(en attente)";
b1.disabled = true;
setTimeout(() => {
alert("message");
b1.textContent = previousContent;
b1.disabled = false;
}, 2000);
});
Dans l'exemple précédent,
pourquoi utiliser la fonction setTimeout
et non une fonction qui bloquerait l'exécution pendant 2s,
comme on le ferait (par exemple) en Python,
à l'image de l'exemple ci-dessous ?
// ⚠ MAUVAIS EXEMPLE ⚠
let previousContent = b1.textContent;
b1.textContent = "(en attente)";
b1.disabled = true;
sleep(2000); // fonction imaginaire (n'existe pas en JS)
alert("message");
b1.textContent = previousContent;
b1.disabled = false;
Note
La fonction sleep
n'existe pas réellement en Javascript,
et pour cause puisque ce n'est pas la bonne manière de faire.
Loupe vous permet de visualiser la manière dont les événements sont gérés en Javascript.
La vidéo qui sert d'introduction est également une bonne introductions aux mécanismes mis en œuvre.
let
),
c'est le bloc entre accolades dans lequel elle est déclarée.f
est donc accessible par les fonctions
(anonymes ou non) définies à l'intérieur de f
.b1
est définie au chargement du script,
mais « survit » à cette fonction,
puisqu'elle est réutilisée au clic sur ce bouton,
et encore deux secondes plus tard,
dans le callback de la fonction setTimeout
.Note
On peut également forcer un listener à se déclencher à la descente
(capture d'un événement) plutôt qu'à sa remontée (bubbling).
Pour cela on passera true
en troisème paramètre de
addEventListener.
target
: l'élément le plus spécifique concerné par l'événement ;type
: le type d'événement (click
, mouseover
...)document.getElementsByTagName("body")[0]
.addEventListener("click", (evt) => {
let msg = document.getElementById("msg");
if (evt.target.tagName === "BUTTON") {
msg.textContent = "Vous avez cliqué sur " +
evt.target.textContent;
} else {
console.log(evt.target);
msg.textContent = "Vous avez raté les boutons...";
}
});
AJAX signifie
... mais en pratique, on peut échanger n'importe quoi avec le serveur, pas uniquement du XML, et notamment du JSON.
Note
AJAX permet donc aux pages HTML d'un site de communiquer avec l'API JSON de ce même site.
fetch('http://example.org').then((response) => {
// cette fonction est appelée lorsque
// les en-têtes de la réponse ont été reçu
if (!response.ok) {
throw ("Error " + response.status);
}
return response.json() // attend la contenu
}).then((data) => {
// cette fonction est appelée lorsque
// le contenu de la réponse a été reçu,
// et analysé comme du JSON
do_something_with(data);
}).catch((err) => {
// cette fonction est appelée en cas d'erreur
console.log(err);
});
Note
La fonction fetch
est disponible dans les navigateurs modernes.
Elle succède à l'ancienne méthode, nommée XMLHttpRequest
,
encore très utilisée.
fetch
§method
indique la méthode HTTP à utiliser (GET par défaut),headers
contient les en-têtes à utiliser (sous forme d'un objet JS),body
contient, le cas échéant, le contenu de la requête ;fetch
§Exemple de requête POST :
fetch("/api/Appointments/", {
method: 'POST',
headers: { "content-type": "application/json" },
body: JSON.stringify(appointment_data),
}).then((response) => {
if (!response.ok) { throw new Error("POST failed"); }
}).catch((err) => {
alert(err);
});