site de Fabien Torre


Notes de cours sur le langage JavaScript

Introduction à la programmation JavaScript, à son interaction avec l'utilisateur et le code HTML/CSS à travers le DOM. Manipulation du canvas html5 et programmation Ajax (XMLHttpRequest et Fetch).

Dans ce cours, nous commençons par les éléments de base du langage JavaScript, en parallèle avec le langage de description vu en cours d'algorithmique (variables, types simples, structures de contrôle, type tableau, procédures et fonctions, etc.). Nous faisons ici le choix de ne pas insister sur les aspects programmation orientée objet du JavaScript.

Dans un deuxième temps, nous nous intéressons à l'utilisation de JavaScript pour la prise en charge des interactions avec le visiteur d'une page web : la prise en compte de ses actions et la modification dynamique du document HTML.

Puis nous regardons comment JavaScript permet de gérer l'objet HTML5 qu'est le canvas.

Enfin, nous terminons avec les méthodes de programmation AJAX.

Types simples, variables, expressions et instructions JavaScript

Instructions et blocs d'instructions

Les scripts JavaScript trouvent leur place au sein de pages HTML. Ainsi, en html5, le code JavaScript doit être encadré par une simple balise <script>.

Dans le langage JavaScript, les blocs d'instructions sont délimités par des accolades : { est l'équivalent d'un Début, } d'une Fin.

Chaque instruction est impérativement suivie d'un point-virgule (;).

Types et variables

JavaScript autorise la manipulation de types classiques : booléens, entiers, réels, caractères et chaîne de caractères et tableaux. Cela dit les types ne sont pas déclarés, uniquement les variables.

let x;             // simple déclaration
let pi     = 3.14; /* déclaration
                      et affectation d'une valeur */
let prenom = 'toto';

Notons sur cet exemple les deux syntaxes possibles pour écrire des commentaires dans le code JavaScript. // est réservé à un commentaire qui s'étend jusqu'à la fin de la ligne mais pas au-delà. /* et */ permettent d'encadrer un commentaire, éventuellement sur plusieurs lignes.

La déclaration d'une variable se fait à l'aide du mot-clef let. Avec let la portée de la variable se restreint au bloc dans laquelle la variable est définie, c'est-à-dire au jeu d'accolades ouvrante/fermante le plus proche contenant la déclaration.

Comme suggéré ci-dessus, le symbole = permet à l'affectation d'une valeur à une variable. Un test d'égalité, qui lui ne modifie en rien les variables, sera exprimé par le symbole ==.

Opérateurs

Nous disposons en JavaScript des opérateurs arithmétiques classiques : +, -, *, /, % pour l'opération modulo, et de l'opérateur de concaténation entre chaînes de caractères noté par un plus (+, comme pour l'addition entre entiers).

let i = 10;
i = i + 1;
i = i + 9;
let texte = 'La variable i vaut '+i;
texte = texte+"\n";

Nous retrouvons également les habituels opérateurs logiques : le ET (noté &&), le OU (noté ||) et le NON (noté !).

Notons enfin que les comparaisons comme < peuvent porter sur des nombres mais aussi sur des chaînes de caractères (il s'agit alors d'une comparaison alphabétique).

Chaînes de caractères et instructions de sortie

Le langage JavaScript permet de délimiter les chaînes de caractères soit par des apostrophes, soit par des guillemets. Il est pratique d'utiliser les guillemets lorsque le texte contient une apostrophe, et vice-versa. Il arrive aussi parfois que les guillemets soient déjà utilisés par html, auquel cas on préfère les apostrophes. Enfin, il est aussi possible d'utiliser un backslash (signe \) pour neutraliser la signification JavaScript d'un caractère.

L'affichage est réalisé à l'aide de la méthode write de l'objet document : il s'agit d'écrire du texte ou des balises au sein du code HTML, à l'endroit où est placé le script.

let prenom = 'Toto';
document.write("salut ");
document.write(prenom);
document.write("<p>ça va aujourd'hui ?</p>");
document.write('<p>oui, ça va aujourd\'hui !</p>');

Il est également possible d'envoyer des affichages vers la console du navigateur et même de « typer » ces affichages à l'aide des instructions suivantes : console.log(), console.info(), console.debug(), console.warn() et console.error(). L'instruction console.clear() permet d'effacer le contenu de la console.

Fonctions mathématiques qui peuvent servir

JavaScript met à notre disposition des fonctions mathématiques à travers l'objet Math dont certaines pourraient nous servir.

// les arrondis : en dessous, au plus proche, au dessus
Math.floor(...)
Math.round(...)
Math.ceil(...)

// de l'aléatoire : un nombre entre 0 et 1
Math.random()

// de la géométrie : la valeur de Pi
Math.PI

Math.floor et Math.random nous permettront de choisir au hasard une case dans un tableau. Math.PI nous permettra de tracer un cercle dans le canvas.

Structures de contrôle en JavaScript

Modulo les notations propres à JavaScript, nous retrouvons les structures de contrôle classiques, en particulier celles vues en cours d'algorithmique.

Ainsi, le si alors sinon a la forme générale suivante.

if (une condition ici) {
  // des instructions ici
} else {
  // des instructions ici
}

La boucle tant que, elle, s'exprime comme suit :

while (une condition ici) {
  // des instructions ici
}

ce qui donne sur un exemple comptant de un à dix : 

let i=0;                 # initialisation d'une variable i
while (i<10) {           # tant que et sa condition
    document.write(i); # affichage
    i = i+1;             # incrémentation de la variable i
}

Enfin, la boucle pour, trois éléments doivent être fournis : une variable avec son initialisation, une condition de type tant que et une instruction à effectuer à chaque passage dans la boucle (typiquement une mise à jour de la variable associée à la boucle).

for ( initialisation ; condition pour continuer ; progression) {
    # des instructions ici
}

... ce qui nous permet de revisiter notre exemple avec une forme plus compacte :

for (let i=0 ; i<10 ; i=i+1) {
    document.write(i); # affichage
}

D'autres boucles sont proposées par JavaScript mais elles sont dédiées à l'énumération des éléments d'un tableau.

Structures de données JavaScript : les tableaux

Deux types de tableaux :

  • les tableaux classiques : pas de contrainte sur le contenu des cases, celles-ci sont numérotées à partir de 0 ;
  • les tableaux associatifs dont la particularité est que les cases ne sont plus indicées par un numéro mais par un texte.

Manipulation des tableaux JavaScript

Tout d'abord la déclaration d'un tableau et l'affectation de valeurs à ses cases.

// définition d'un tableau vide et remplissage des cases
let notes = [];
t[0]  = 10;
t[1]  = 5;
t[2]  = 20;

// autre syntaxe pour définir un tableau
let notes = [10,5,20,14,2];

À noter que la taille d'un tableau t est accessible à travers l'expression « t.length ».

Enfin, les tableaux associatifs :

let mails = [];
mails['torre'] = 'torre@univ.fr';
mails['toto']  = 'toto.machin@free.fr';
document.write('Mail de toto = '+mails['toto']);

Parcours de tableaux JavaScript : les boucles for in et for of

Ces boucles sont dédiées aux parcours des tableaux.

// syntaxes générales pour le parcours d'un tableau t
for (let k in t) {
    // des instructions ici portant sur t[k]
}
  
for (let v of t) {
    // des instructions ici portant sur v
}

Mise en œuvre sur un tableau de notes :

// définition d'un tableau classique
let notes = [10,12,18,20,4];

// parcours des indices avec for in
for (let i in notes) {
    document.write(notes[i]);
}

// boucle classique équivalente au for in
for (let i=0 ; i<notes.length ; i=i+1) {
    document.write(notes[i]);
}

// parcours des valeurs avec for of
for (let note of notes) {
    document.write(note);
}

Dans le cas d'un tableau associatif, la boucle for in permet de parcourir les clefs du tableau :

// définition d'un tableau associatif
let carnet = [];
carnet["pierre"]  = "19 ans";
carnet["paul"]    = "26 ans";
carnet["jacques"] = "30 ans";

// parcours des clefs et affichage des valeurs du tableau
for (let nom in carnet) {
  document.write("la clef vaut : " + nom);
  document.write(", la valeur associée est : ",carnet[nom],"<br>");
}

Fonctions et procédures en JavaScript

Rappelons que procédures et fonctions sont semblables sur bien des points. Elles permettent d'isoler un bloc d'instructions, de le nommer et ainsi le rendre réutilisable dans différents contextes. Elles peuvent utiliser des paramètres et contenir des instructions quelconques.

En revanche, une fonction doit toujours se terminer par le renvoi d'un résultat (à l'aide du mot-clef return en JavaScript), tandis qu'une procédure ne renvoie jamais aucun résultat (sinon ce serait une fonction !). Cela signifie en particulier qu'un appel à une fonction se trouvera souvent dans la partie droite d'une affectation, ou embarqué directement dans un test, ce qui ne sera jamais le cas pour un appel de procédure.

Définition et utilisation d'une procédure

// forme générale d'une procédure
function nom_de_la_procédure (paramètres) {
  // des instructions ici
}
# définition d'une procédure
function est_voyelle_procédure_tantque (lettre) {

    let voyelles = ["a","e","i","o","u","y"];

    let i = 0;
    while ((i<voyelles.length) && (lettre != voyelles[i])) {
	i = i+1;
    }

    # affichage de la réponse, pas de return
    if (i<voyelles.length) {

	document.write("« ",lettre," » est une voyelle.");
	
    } else {

	document.write("« ",lettre," » N'est PAS une voyelle.");
	
    }
}

# appels à la procédure
est_voyelle_procédure_tantque("a");
est_voyelle_procédure_tantque("b");

Définition et utilisation d'une fonction

// forme générale d'une fonction
function nom_de_la_fonction (paramètres) {
  // des instructions ici
  return(résultat);
}
# définition d'une fonction
function est_voyelle_fonction_tantque (lettre) {

    let voyelles = ["a","e","i","o","u","y"];

    let i = 0;
    while ((i<voyelles.length) && (lettre != voyelles[i])) {
	i = i+1;
}

    # renvoi de la réponse, pas d'affichage      
    return (i<voyelles.length);

}

# appel à la fonction dans la condition d'un if et affichage de la réponse
for (lettre of ["a","b"]) {
    if (est_voyelle_fonction_tantque(lettre)) {
	document.write("« ",lettre," » est une voyelle.");
    } else {
	document.write("« ",lettre," » N'est PAS une voyelle.");
    }
}

Gestion des événements et des actions en JavaScript

Le couple HTML + CSS amène à des documents essentiellement statiques. Nous avons vu que certains calculs peuvent être automatisés avec document.write. Nous regardons maintenant comment produire des documents de manière dynamique :

  • côté serveur : il est possible d'utiliser un langage comme PHP associé à une base de données SQL ;
  • côté client : ce sont les actions de l'utilisateur, puis la modification du document en fonction de ces actions et à l'aide de JavaScript, qui produisent une page web dynamique.

Dans cette section, nous nous intéressons aux événements déclenchés par l'utilisateur, la section suivante porte sur la modification du document.

Événements que l'on peut capturer avec JavaScript

Voici les principaux événements que nous allons pouvoir traiter.

  • onload : événements déclenchés à l'arrivée sur la page,
  • onunload : événements déclenchés au départ de la page,
  • onclick, onmousedown, onmouseup, onmousemove, onmouseover, onmouseout : événements associés aux clics et déplacements de la souris,
  • onkeypress, onkeydown, onkeyup : événements provoqués par l'appui d'une touche au clavier,
  • onsubmit, onchange : événements associés à la manipulation d'un formulaire par l'utilisateur.

Ces événements sont également des noms d'attributs HTML, le contenu de ces attributs sera du JavaScript. De manière générale, JavaScript permet d'associer une instruction JavaScript à chaque événement : soit l'appel à une fonction de base JavaScript, soit l'appel à l'une des nos propres procédures.

Fonctions JavaScript associables à une action de l'utilisateur

Nous venons de capturer un événement, il reste à lui associer une action, c'est-à-dire un code JavaScript à exécuter, sachant que document.write n'est plus utilisable dans ce contexte.

Nous pouvons en revanche jouer sur les actions JavaScript suivantes :

  • alert ouvre une fenêtre avec un message donné,
  • modifier window.location pour aller vers une autre page,
  • setTimeout et setInterval permettent respectivement de différer et de répéter une instruction ;
  • focus permet d'activer un élément de la page (comme la case à remplir obligatoirement dans un formulaire), blur de le désactiver.

Exemples :

// déclenchement d'une alerte immédiate (alert)
<button onclick="alert('Coucou !')">cliquez ici !<button>

// déclenchement d'une alerte dans une demi-seconde (setTimeout)
<button onclick="setTimeout('alert(\'Surprise !\')',500)">
cliquez ici !<button>

// répétition toutes les 5 secondes (setInterval)
let clock_id = setInterval('alert(\'hi hi !\');',5000);
...
clearInterval(clock_id); // fin de la répétition

Informations sur un événement capturé

Lorqu'un événement survient, un objet nommé event est créé pour décrire cet événement.

Événements du clavier

En particulier, dans le cas d'une touche pressée au clavier, cette variable permet de connaître cette touche à travers la propriété event.key. Dans le cas d'un caractère imprimable, event.key nous donne le caractère lui-même. Dans les autres cas, event.key fournit une chaîne de caractères correspondant à la touche pressée :

  • Delete et Backspace pour les suppressions,
  • Enter pour la touche entrée,
  • ArrowLeft, ArrowUp, ArrowRight, ArrowDown pour les flèches,
  • etc.

Cela permet par exemple de lancer une alerte quand on presse la flèche vers le haut :

<body onkeyup="if (event.key=='ArrowUp') { alert('haut !'); }">

Souvent le code JavaScript associé à un tel événement ne restera pas lisible au sein d'un attribut html et il conviendra alors de créer à part une procédure à laquelle on va transmettre la variable event.

<script>

function gere_frappe (e) {           // procédure qui traite un événement survenu au clavier
    if (event.key=='ArrowUp') {
      alert('vers le haut !');
    } else if (event.key=='ArrowDown') {
      alert('vers le bas !');
    }
}

</script>    

<body onkeyup="gere_frappe(event);"> <!-- appel à la procédure quand l'événement survient -->

Événements de la souris

Enfin, dans le cas d'un clic à la souris dans la page, l'objet event nous fournit les coordonnées du pixel cliqué à travers les propriétés event.pageX et event.pageY.

Modification du document : le modèle DOM en JavaScript

La seconde étape pour avoir du dynamique côté utilisateur, consiste à modifier le document à l'aide d'instructions JavaScript.

Généralités sur le « DOM »

Il faut savoir que les navigateurs ont en mémoire un modèle du document, c'est sur lui qu'il nous faut intervenir. Nous allons parler de DOM (Document Object Model), avec deux sens possibles :

  1. DOM désigne la structure d'arbre représentant le document et présente dans dans la mémoire du navigateur. Nous ne savons pas ce qu'est cette structure dans le détail, elle peut être différente selon les navigateurs et les langages de programmation utilisés. C'est pourtant cet arbre-document que nous voulons modifier.
  2. DOM est aussi une API (Application Programming Interface, ou interface de programmation) qui nous fournit les moyens d'interagir avec l'arbre-document. C'est une recommandation du W3C pour gérer le contenu de documents XML, HTML en particulier. Une telle API standardisée nous permet d'écrire des scripts indépendants des navigateurs, résistant aux modifications futures des navigateurs, et que nous pourrions aisément traduire dans d'autres langages que JavaScript implémentant cette API (voir par exemple ces notes de cours sur DOM en Python).

En résumé, DOM désigne à la fois l'objet que nous voulons modifier et la boite à outils qui va nous permettre de le faire.

Nous avons jusque là utilisé document.write pour insérer automatiquement du contenu. Savons-nous ce que fait subir exactement cette méthode au document ? Non, en particulier nous savons ni où s'ajoute le contenu produit dynamiquement, ni si nous pouvons réellement greffer un nouveau sous-arbre, ni enfin ce qui se produit si le code HTML ainsi ajouté n'est pas du XML valide. De plus, document.write ne permet ni d'accéder à la CSS, ni de supprimer une partie du contenu. Finalement, cette méthode n'est clairement pas la bonne pour modifier un document.

Avant, d'examiner les méthodes du DOM, considérons quelques exemples de modifications du document que nous voudrions être capables de réaliser dynamiquement :

  • rendre visible/invisible une partie du document,
  • modifier un élément de style de la page,
  • changer une image,
  • remplissage automatique de formulaires ou test de validité des données saisies dans un formulaire avant envoi au serveur,
  • etc.

Notons que, dans tous les cas, les identifiants HTML (attributs ID) vont jouer un rôle crucial pour repérer les nœuds de l'arbre.

On distingue souvent le DOM HTML (utilisant les propriétés propres au html comme l'existence d'identifiants ou de classes), du DOM XML (plus générique).

DOM par l'exemple

Dans les exemples suivants, instructions DOM HTML et instructions DOM XML sont mêlées.

// nous jouons avec les couleurs
document.fgColor = 'blue'
document.bgColor = 'red'

// nous changeons le texte d'une case de formulaire
document.form1.coul.value = 'rouge'

// curseur dans la case à remplir
document.form1.adresse.focus();
// le curseur quitte cette case
document.form1.adresse.blur();

// nous changeons une image
document.ecran.src = file;
// idem avec DOM XML et la modification d'un attribut
document.ecran.setAttribute('src',file);

// récupération d'un élément de la page...
e = document.getElementById('divcomment');
// ... nous le rendons invisible par modification CSS
e.style.visibility = 'hidden';

// pareil en une seule ligne
document.getElementById('divcomment').style.visibility = 'hidden';

// modification d'un attribut
e.setAttribute('style','color: #666699;');

// suppression d'un attribut
document.getElementById(bname).removeAttribute('disabled');

// définition du contenu d'un élément
e.innerHTML = 'coucou';

// ajout d'une branche à l'arbre DOM
t = document.createTextNode('coucou');
p = document.createElement('p');
p.appendChild(t);
e.appendChild(p);

// autres méthodes d'ajout
e.prepend(p)
e.insertBefore(p,e.firstChild)
// (ces deux dernières instructions sont équivalentes)

// fils et nombre de fils d'un élément
e.childNodes
e.childNodes.length

// suppression d'un élément
e.remove();

Récapitulatif des principales instructions DOM

DOM HTML.

getElementById(id)            // récupération de l'élément portant l'identifiant donné

getElementsByClassName(class) // récupération du tableau des éléments de la classe donnée

e.style                       // modification du style d'un élément

e.attribute                   // accès/modification à un attribut de l'élément (src, value, etc.)

e.innerHTML                   // accès au contenu HTML, bien formé, de l'élément

DOM XML.

getElementsByTagName(tag) // récupération des éléments dans un tableau

e.getAttribute(a)         // récupération de la valeur de l'attribut a de l'élément e

e.setAttribute(a,v)       // définition de la valeur de l'attribut a pour l'élément e

e.removeAttribute(a)      // suppression de l'attribut a de l'élément e

createElement(tag)        // création d'un nouvel élément

createTextNode(texte)     // création d'une nouvelle feuille textuelle

e.appendChild(nf)         // ajout d'un nouveau fils nf à l'élément e, en dernière position

e.prepend(nf)             // ajout d'un nouveau fils nf à l'élément e, en première position

e.insertBefore(nf,pf)     // ajout d'un nouveau fils nf à l'élément e, avant le fils existant pf

e.firstChild              // premier fils de e

e.lastChild               // dernier fils de e

e.children                // tableau des enfants-éléments de e

e.childNodes              // tableau des enfants-nœuds de e

e.attributes              // tableau des attributs de e

Pour quelques instructions de plus... sur les nœuds de l'arbre DOM.

n.nodeType   // type du nœud n

n.nodeValue  // texte du nœud n (s'il est de type 3)

n.nodeName   // nom de l'élément (si le nœud n est de type 1)

n.parentNode // nœud père du nœud n

Enfin, notons la possibilité d'avoir recours à des sélecteurs CSS pour repérer des nœuds dans l'arbre DOM, à l'aide de la méthode querySelector (qui fournit le premier nœud qui correspond au sélecteur) et de la méthode querySelectorAll (qui fournit tous les nœuds qui matchent).

let body         = document.querySelector("body");                  // par tag, un seul nœud visé
let introduction = document.querySelector("#intro");                // par identifiant

let paragraphes  = document.querySelectorAll("p");                  // par tag name
let ecolos       = document.querySelectorAll("p.ecolo");            // par nom de classe
let ecolos       = document.querySelectorAll("p[class='ecolo']");   // par nom de classe testé comme un attribut
let francophones = document.querySelectorAll("section[lang='fr']"); // avec condition sur un attribut quelconque

Association dynamique d'un événement à un élément du DOM

Il est possible d'associer un événement et son traitement à un élément, non pas statiquement dans le code HTML comme nous l'avons vu, mais dynamiquement, en JavaScript. Cela se fait à l'aide de la méthode addEventListener. Par exemple, notre précédent code html/JavaScript :

<body onkeyup="gere_frappe(event);"> <!-- appel à la procédure quand l'événement survient -->

peut s'écrire en pur JavaScript :

// association élément/événement/procédure
document.addEventListener("onkeyup",gere_clic);

Parfois, l'événement est associé à un élément particulier qu'il convient de récupérer d'abord dans l'arbre DOM, par exemple pour le clic sur une image :

// procédure pour gérer un événement de type clic
function gere_clic(e) {
  alert(e.pageX + ' × ' + e.pageY);
}
    
// récupération d'une image du document à l'aide de son identifiant
let image = document.getElementById("ecran");

// association élément/événement/procédure
image.addEventListener("click",gere_clic);

L'objet canvas de HTML5 et JavaScript

Initialisations

Le canvas est un objet introduit dans html5 mais qui ne peut être manipulé que par JavaScript. Ensemble ils permettent du graphisme animé, par exemple pour programmer des jeux. En cela, le couple canvas+JavaScript a concurrencé, et finalement remplace, Flash qui auparavant permettait ces animations.

Côté HTML, nous allons introduire la balise <canvas>, vide de contenu, mais avec un identifiant et des dimensions.

<canvas id="world" width="..." height="..."></canvas>

Ajoutons que l'apparence du canvas (marges, bordures, etc.) peut être spécifiée en CSS.

Côté JavaScript, un code s'occupant du canvas commencera systématiquement par ces deux lignes :

canvas  = document.getElementById('world');
context = canvas.getContext('2d');

La première permet de récupérer l'objet canvas à partir de son identifiant. Avec la seconde, on obtient un objet que l'on place dans une variable context, lequel va nous permettre de dialoguer avec le canvas à travers des instructions deux dimensions (tracer un rectangle, un cercle, etc.). Il n'existe pas d'autre contexte que 2D !

Pour ces instructions de dessin en 2D, le canvas utilise un système de coordonnées dont l'origine (0,0) se trouve en haut à gauche.

Dessiner dans le canvas html5

Ci-dessous des exemples de traçage en couleur de différentes formes, de remplissage, de gommage, etc.

// changement de couleurs, de trait et de remplissage
context.strokeStyle = '#000';
context.fillStyle   = '#6F6';

// dessin de rectangle, un creux et un plein
context.strokeRect(x,y,largeur,hauteur);
context.fillRect(x,y,largeur,hauteur);

// forme générale pour un arc
context.arc(x,y,rayon,angledeb,anglefin,antihoraire);
// les angles sont mesurés par rapport à l'horizontal vers la droite

// dessin d'un disque avec bord
context.beginPath();
context.arc(200,150,60,0,2*Math.PI,false);
context.closePath();
context.fill();
context.stroke();

// tracé d'une ellipse (deux rayons et une inclinaison)
context.beginPath();
context.ellipse(200,200,50,75,Math.PI/4,0,2*Math.PI);
context.closePath();
context.stroke();

// dessin d'un cercle avec l'instruction ellipse
context.beginPath();
context.ellipse(200,200,50,50,0,0,2*Math.PI);
context.closePath();
context.stroke();

// tracé de deux traits
context.beginPath();             
context.moveTo(80,250);
context.lineTo(90,250);
context.moveTo(110,250);
context.lineTo(120,250);
context.stroke();

// nettoyage d'une zone rectangulaire
context.clearRect(90,280,20,20);

// écriture de texte
context.fillStyle = 'black';
context.font = "bold 15px sans-serif";
context.fillText("-> coucou !",120,295);

Association d'un code JavaScript à un événement du canvas

À nouveau, il est possible d'associer une procédure JavaScript à un événement cette fois lié au canvas, ici un clic :

<canvas id="world" width="..." height="..." onclick="gere_clic(event)"></canvas>

Outre cette syntaxe html, il est possible d'associer un événement à une balise directement en JavaScript. Par exemple, pour associer une action JavaScript au clic sur le canvas, nous écrivons :

canvas.addEventListener("click", gere_clic);

Dans les deux cas, un clic à la souris dans le canvas déclenchera l'exécution de la procédure gere_clic (qu'il faut donc de définir). L'événement clic fournit les coordonnées du clic dans la fenêtre du navigation. Si l'on veut les coordonnées dans le canvas lui-même, il convient d'ôter les distances du canvas aux bords du navigateur.

function gere_clic(e) {
  ...
  x = e.pageX - canvas.offsetLeft;
  y = e.pageY - canvas.offsetTop;
  ...
}

Programmation AJAX

AJAX signifie Asynchronous JavaScript And XML. Au-delà de l'acronyme, il s'agit de réaliser les tâches suivantes :

  • envoi d'une requête http(s) depuis le code JavaScript d'une page déjà chargée dans le navigateur web,
  • de manière asynchrone, c'est-à-dire sans bloquer le navigateur, celui-ci n'est pas dans l'attente de la réponse et continue,
  • réception de la réponse sous une forme plus ou moins structurée (XML, JSON, html ou texte pur),
  • modification du DOM pour intégrer les nouvelles données reçues.

Ce contexte permet plusieurs variations, notamment :

  • deux formats d'échange de données : XML/html ou JSON ;
  • deux types d'application : API ou web scraping ;
  • deux méthodes AJAX disponibles en JavaScript, la méthode historique XMLHttpRequest et la méthode plus moderne Fetch.

Programmation AJAX avec XMLHttpRequest

La première méthode (XMLHttpRequest) envoie la requête depuis une première procédure, puis l'événement d'arrivée de la réponse déclenche une seconde procédure.

La méthode XMLHttpRequest ramenant du XML :

let requete; // variable globale utilisée par les deux procédures

function actualisation () {

    if (requete.readyState == 4) {        // la réponse est arrivée

	let docxml = requete.responseXML; // réponse sous forme d'un DOM

        // traitement du DOM récupéré et mise à jour de la page

    }
}


function demande () {

    requete = new XMLHttpRequest();

    requete.onreadystatechange = actualisation;           // assocation événement/action

    requete.open('GET','url_qui_va_fournir_les_données'); // url à renseigner
    // par défaut, la requête est effectuée en asynchrone
	
    requete.send();

}

La méthode XMLHttpRequest ramenant du JSON :

let requete; // variable globale utilisée par les deux procédures

function actualisation () {

    if (requete.readyState == 4) {                   // la réponse est arrivée

	let data = JSON.parse(requete.responseText); // obtention d'un objet JavaScript à partir du texte reçu

        // traitement des données récupérées et mise à jour de la page

    }
}

function demande () {
    requete = new XMLHttpRequest();
    requete.onreadystatechange = actualisation;           // assocation événement/action
    requete.open('GET','url_qui_va_fournir_les_données'); // url à renseigner
    requete.send();
}

La valeur 4 pour la propriété readyState indique que la transaction est terminée, mais on peut vouloir tester en plus que tout s'est bien passé, avant d'accéder au contenu de la réponse. Dans ce cas, on s'assurera que la propriété status a pour valeur 200.

Programmation AJAX avec Fetch

La seconde méthode (Fetch) utilise les possibilités pour JavaScript de l'exécution asynchrone et de faire une pause au sein d'une même procédure pour attendre la réponse.

La méthode Fetch ramenant du JSON :

async function récupération () {

    let retour = await fetch('url_qui_va_fournir_les_données'); // url à renseigner

    let data   = await retour.json();                           // récupération d'une structure de données JavaScript

    // traitement des données récupérées et mise à jour de la page
}

La méthode Fetch ramenant du XML :

async function récupération () {

    let retour = await fetch('url_qui_va_fournir_les_données'); // url à renseigner
    let texte  = await retour.text();                           // récupération d'un texte XML

    // construction d'un DOM à partir du texte XML récupéré
    let parser = new DOMParser();
    let docxml = parser.parseFromString(texte,"text/xml");
    // ou, si la source est en html : let docxml = parser.parseFromString(texte,"text/html");
    
    // traitement du DOM construit et mise à jour de la page
}

À nouveau, il est possible de vérifier que tout s'est bien passé en testant au choix la propriété status ou la propriété ok.


Accueil > Enseignement > Cours > Programmation > JavaScript
(contenu mis à jour )
site de Fabien Torre, université de Lille

Description

Survoler un lien de navigation pour lire sa description ici...


Une photo au hasard

Week-end royal.

Jardin chevillais.

(le 23 juin 2007)

Fleurs de courgette.