Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Warning: Undefined array key 2 in /home/goupillf/wiki.goupill.fr/lib/plugins/codeprettify/syntax/code.php on line 214
Table des matières
Javascript dans une page web
JS, dans une page web, permet une programmation événementielle.
Cliquer sur un bouton, passer le curseur de la souris au-dessus d'une zone, écrire dans un champ de texte… Ce sont des événements qui nous permettent d’interagir avec une page web.
JS permet de capter ces événements et de déclencher un programme. Un clic de souris capté par JS permettra d'ajouter un élément, dérouler un menu, changer une couleur, valider une saisie, envoyer un message vers le serveur…
Pour l'ensemble de ce cours, vous aurez besoin des fichiers contenus dans js.zip. Décompressez cette archive dans un dossier local.
Premier événement
À faire : page_1.html est un fichier de l'archive. Ouvrez le dans un navigateur.
<!DOCTYPE html>
<html> <!-- page_1.html -->
<head>
<meta charset="utf-8">
<title>page 1</title>
<link rel="stylesheet" type="text/css" href="styles.css">
</head>
<body>
<p>Ci-dessous, trois blocs <i>div</i> en couleur. Quand on clique sur le carré rouge, un message s'affiche.</p>
<div class="carre rouge" onclick="alert('Interdiction d\'appuyer sur le bouton rouge !');"></div>
<div class="carre vert"></div>
<div class="carre bleu"></div>
</body>
</html>
Notez en ligne 10 l'utilisation de la fonction alert.
À faire : modifiez le code html pour que les autres boutons lancent un message également.
Environnement de travail
Avant d'aller plus loin, vous allez découvrir les outils, disponibles sur Chrome ou Firefox, qui permettent de bien travailler quand on programme dans une page web.
Appuyez CTRL + MAJ + I. Un panneau s'ouvre à droite ou en bas – vous pouvez le déplacer. Il est composé de différents onglets :
- Inspecteur : vous pouvez sélectionner n'importe quel item sur la page et par exemple analyser ses attributs de style.
- Console : messages d'erreurs ou autres.
- Réseau : sera utile quand on voudra échanger des données avec un serveur.
Sur Firefox il y a même un outil permettant de voir comment la page sera sur un écran de téléphone !
<!DOCTYPE html>
<html>
<head> <!-- page_2.html -->
<meta charset="utf-8">
<title>page 2</title>
<link rel="stylesheet" type="text/css" href="styles.css">
</head>
<body>
<div class="carre rouge" onclick="console.log('On vous a déjà prévenu : Interdiction d\'appuyer sur le bouton rouge !');"></div>
<div class="carre vert"></div>
<div class="carre bleu" onclick="x = 2 + y;"></div>
</body>
</html>
À faire : ouvrez page_2.html dans un navigateur. Ouvrez la console. Appuyez sur les boutons. Que constatez-vous ?
Plus gros programme
On rencontre le même problème qu'avec le style : s'il faut écrire le code JS à l'intérieur des balises html, cela va être peu lisible et rapidement impossible à gérer.
Une première étape consiste à placer le code JS dans la zone <head>. On peut définir des fonctions et appeler ces fonctions lors d'un événement.
Modifier la page
Dans l'exemple qui va suivre, on va faire mieux que d'afficher un popup d'alerte ou log en console, nous allons modifier la page.
JS peut accéder à la page à l'aide d'une variable document, et cette variable est dotée de fonctions qui permettent de lire le contenu, en ajouter, modifier les styles…
Quand on accède aux éléments de la page, la page est appelé le DOM pour Document Object Model. Le DOM, c'est la page html avec toutes ses nœuds structurés en arbre : <body> a des enfants, par exemple des <div> qui ont eux-mêmes des enfants, par exemple <p>…
Exemple
- on crée un élément de texte (on parle de nœuds, en anglais node),
- pour contenir ce texte on crée un élément paragraphe (balise de type
<p>, - on récupère le nœud de la zone réservée aux messages qui est identifiée par un attribut
id = “divMessages”, - on ajoute le le nœud de texte dans le noeud paragraphe et le nœud paragraphe dans le nœud
divMessages.
<!DOCTYPE html>
<html> <!-- page_3.html -->
<head>
<meta charset="utf-8">
<title>page 3</title>
<link rel="stylesheet" type="text/css" href="styles.css">
<script language="javascript">
let nombreClicks = 0;
function addMessage(message){
nombreClicks++;
let divMessages = document.getElementById("divMessages");
let nouvelleLigne = nombreClicks+" : " + message;
let nodeText = document.createTextNode(nouvelleLigne);
let nodeParagraph = document.createElement("p");
nodeParagraph.appendChild(nodeText);
divMessages.appendChild(nodeParagraph);
}
</script>
</head>
<body>
<h2>Démonstration</h2>
<p>Cliquez sur les boutons.</p>
<div class="carre rouge" onclick="addMessage('clic sur rouge');"></div>
<div class="carre vert" onclick="addMessage('clic sur vert');"></div>
<div class="carre bleu" onclick="addMessage('clic sur bleu');"></div>
</body>
<div id="divMessages"></div>
</html>
À faire : ouvrez page_3.html dans un navigateur. Vérifiez le bon fonctionnement. Modifiez le code pour que les messages s'affichent dans une liste ordonnée type <ol>.
Script à part
Poussons la logique de séparation un pas plus loin : Nous déplaçons le JS dans un fichier à part – dans un site moderne, la taille totale du JS peut être plus grande que celle du html !
Dans le code ci-dessous, le script à été déplacé dans le fichier annexe script_4.js.
Remarquez qu'il reste tout de même du code JS dans la page en lignes 11-13.
<!DOCTYPE html>
<html> <!-- page_4.html -->
<head>
<meta charset="utf-8">
<title>page 4</title>
<link rel="stylesheet" type="text/css" href="styles.css">
<script type="text/javascript" src="script_4.js"></script>
</head>
<body>
<p>Cliquez sur les boutons.</p>
<div class="carre rouge" onclick="addMessage('clic sur rouge');"></div>
<div class="carre vert" onclick="addMessage('clic sur vert');"></div>
<div class="carre bleu" onclick="addMessage('clic sur bleu');"></div>
<div class="messages"><b>Zone pour les messages</b>
<ol id="listeMessages"></ol>
</div>
</body>
</html>
// script_4.js
// Fichier script mis à part
function addMessage(message){
let nodeMessages = document.getElementById("listeMessages");
let nouvelleLigne = message;
let nodeText = document.createTextNode(nouvelleLigne);
let nodeLi = document.createElement("li");
nodeLi.appendChild(nodeText);
nodeMessages.appendChild(nodeLi);
}
Changer de style
Pour changer l'apparence d'un élément de la page, le plus simple est d'utiliser le style CSS. JS permet d'assigner des styles aux éléments ou d'en enlever.
soit node, un certain nœud du DOM, on peut lui ajouter une classe CSS par la commande :
node.classList.add("nom_de_la_classe");
Le fichier styles.css contient les classes "texte_en_rouge"", "texte_en_bleu"", "texte_en_vert"".
À faire : ouvrez page_4.html dans un navigateur. Testez son bon fonctionnement puis modifiez script_4.js pour que les messages apparaissent une ligne sur deux alternativement en rouge et en bleu.
Script totalement à part
Toujours plus loin dans la séparation, nous essayons d'enlever les dernières traces de JS qui restaient dans le html.
<!DOCTYPE html>
<html> <!-- page_5.html -->
<head>
<meta charset="utf-8">
<title>page 5</title>
<link rel="stylesheet" type="text/css" href="styles.css">
<script type="text/javascript" src="script_5.js"></script>
</head>
<body>
<p>Cliquez sur les boutons.</p>
<div class="carre rouge" id="bouton_rouge"></div>
<div class="carre vert" id="bouton_vert"></div>
<div class="carre bleu" id="bouton_bleu"></div>
<div class="messages"><b>Zone pour les messages</b>
<ol id="listeMessages"></ol>
</div>
</body>
</html>
Le html ne contient plus aucun code JS. Tout le JS est dans le fichier script_5.js.
// script_5.js
// Fichier script mis à part
function addMessage(message){
let nodeMessages = document.getElementById("listeMessages");
let nouvelleLigne = message;
let nodeText = document.createTextNode(nouvelleLigne);
let nodeLi = document.createElement("li");
nodeLi.appendChild(nodeText);
nodeMessages.appendChild(nodeLi);
}
document.getElementById("bouton_rouge").addEventListener(
"click",
function(){ addMessage("clic sur rouge"); });
document.getElementById("bouton_bleu").addEventListener(
"click",
function(){ addMessage("clic sur bleu"); });
document.getElementById("bouton_vert").addEventListener(
"click",
function(){ addMessage("clic sur vert"); });
Remarquez en particulier les lignes 12-20 : En ligne 12-14 par exemple, on accède à l'élément d'id ""bouton_rouge"". Cet élément est bien présent dans le fichier html, en ligne 11. On demande ce nœud d'écouter l'événement clic de souris – addEventListener. On comprend que dès lors, un clic de souris sur cet élément déclenchera une fonction.
À faire : ouvrez page_5.html dans un navigateur. Constatez que cela ne fonctionne pas – pensez à observer la console.
Voici où est le problème : Le script script_5.js est déclaré en début de page html. Il est chargé dès le début alors que le contenu <body> n'es pas encore chargé dans le navigateur. Le nœud d'id ""bouton_rouge"" n'existe pas encore dans le DOM.
La solution est de déclarer le script à la fin de <body> et pas dans <head>.
À faire : faites-le et constatez que maintenant, ça fonctionne.
D'autres événements
Il y a d'autres événements que click !
load: quand l'élément est chargé.
On l'associe souvent à<body>, permet d'attendre que la page est bien chargée.click: déjà vu, c'est le clic souris.dblclick: double clic.mouseover: quand la souris passe au-dessus.mouseout: quand la souris arrête d'être au-dessus.keypress: quand on appuie sur une touche pour entrer un caractère. Utile dans un champ de saisie.input: quand le contenu d'un champ de saisie texte est modifié, à chaque entrée de caractère.change: quand le contenu d'un champ de saisie est modifié et ce changement est validé (un peu différent du précédent)focus: quand l'élément gagne le focus. Dans une page où on trouve plusieurs zones de saisie, celle dans laquelle on est en train d'écrire est celle qui a le focus.blur: perte du focus.submit: dans le cas d'un formulaire (ensemble de champ de saisie avec un bouton “soumettre” ou “Envoyer” ou “ok” ou…) quand le formulaire est validé et peut-être envoyé.
Il y a beaucoup d'événements, inutile de les connaître par cœur… Internet est plein de références permettant de trouver tout ce que l'on a besoin de savoir. Par exemple MDN web docs.
Exemple
<!DOCTYPE html>
<html> <!-- page_6.html -->
<head>
<meta charset="utf-8">
<title>page 6</title>
<link rel="stylesheet" type="text/css" href="styles.css">
</head>
<body>
<h2>Démonstration</h2>
<input type="text" id="champ_saisie">
<div class="messages"><b>Zone pour la réponse</b>
<div id="zone_de_reponse"></div>
</div>
<script type="text/javascript" src="script_6.js"></script>
</body>
</html>
Dans ce code, ligne 10, on a défini :
<input type="text" id="champ_saisie">
Ce champ de saisie est lié, dans le script script_6.js en ligne 3, à l'événement input.
// script_6.js
let villes = ["Paris", "Marseille", "Lyon", ... ]; // j'abrège...
document.getElementById("champ_saisie").addEventListener("input", saisieInput)
// Il y a une suite dans script_6.js
À faire : on aimerait que quand il n'y a aucun résultat apparaisse un message comme Aucun résultat. Faites la modification dans script_6.js.
event
Quand l'événement appelle la fonction, il lui transmet automatiquement un argument. On peut l'appeler e. Il contient un objet représentant l'événement lui même.
Par exemple, dans page_7.html,
<h2>event</h2> <input type="button" id="bouton_event1" value="Cliquez-moi !"> <input type="button" id="bouton_event2" value="Cliquez-moi !">
Associé à, dans script_7.js
// script_7.js
function clickButton(e){
console.log(e);
}
document.getElementById("bouton_event1").addEventListener("click", clickButton );
document.getElementById("bouton_event2").addEventListener("click", clickButton );
À faire : ouvrez page_7.html dans un navigateur, ouvrez la console et cliquez sur l'un des boutons de la section event. Observez ce qui s'affiche en console.
L'objet event qui apparaît en console a beaucoup d'attributs. Ils renseignent sur la nature de l'événement. Par exemple, l'attribut target nous indique quel nœud du DOM est la cible de cet événement. Ici, deux boutons sont attachés au même événement. L'attribut target nous permet de savoir lequel a été cliqué.
À faire : modifiez la fonction clickButton dans script_7.js pour que le texte du bouton cliqué change, passant de "Cliquez-moi !" à "Cliquez-moi ! (1)" au premier clic, puis "Cliquez-moi ! (2)" et ainsi de suite.
this
Le mot clé this désigne celui qui appelle la fonction. On retrouve ce mot clé dans les différents langages sous différentes formes. En Python, on utilise plutôt self.
<h2>this</h2> <!-- page_8.html --> <input type="button" id="bouton_this_gauche" value="Je suis le bouton de gauche"> <input type="button" id="bouton_this_droite" value="Je suis le bouton de droite">
// script_8.js
function quiSuisJe(e){
console.log(this.value);
}
document.getElementById("bouton_this_gauche").addEventListener("click", quiSuisJe );
document.getElementById("bouton_this_droite").addEventListener("click", quiSuisJe );
Dans ce code, le même événement peut être appelé depuis deux boutons – problème semblable au précédent. À l'intérieur de la fonction, le mot clé this désigne le contexte de l'événement. Quand on appuie sur bouton_this_gauche, le contexte est bouton_this_gauche.
À faire : testez en visualisant la console.
Modifiez en ajoutant après les boutons une balise <img> et modifiez la fonction quiSuisJe pour que le bouton de gauche provoque l'affichage de pikachu.jpeg dans la balise <img> et le bouton droit provoque l'affichage de salamèche.jpeg. Les fichiers images sont dans l'archive fournie.
Détourner les balises
Quand on conçoit une page dynamique, on n'a pas vraiment besoin de recharger une page web comme cela se faisait dans le passé. Le clic sur un lien n'a pas besoin de demander au serveur une nouvelle page html. Au contraire, le lien hypertexte <a> déclenche un événement et c'est le script qui se charge de construire la nouvelle page. Le lien est alors détourné de sa fonction première qui est de demander au serveur de fournir une nouvelle page.
Pour une bonne conception, on utilise tout de même la balise <a> :
- on peut parcourir les liens avec le clavier (touche TAB),
c'est une fonctionnalité des navigateurs - les outils d'accessibilité (déficience visuelle par ex.) détectent les liens.
Donc on veut utiliser une balise <a> même si on ne veut pas qu'elle fonctionne comme une balise <a> normal… Voyons un exemple.
<h2>Détourner les balises</h2> <!-- page_9.html --> <a href="fausse_page.html" id="faux_lien">Mon faux lien</a>
// script_9.js
function click_faux_lien(e){
alert('au lieu d\'un lien vous avez une popup !');
e.preventDefault();
}
document.getElementById("faux_lien").addEventListener("click", click_faux_lien );
Dans ce script, la balise <a> est liée à un événement qui provoque l'affichage d'un popup avec alert. En ligne 4, e.preventDefault() commande de ne pas faire ce qui devrait se faire normalement dans ce cas. Cela revient à demander que la balise <a> ne demande pas le chargement de la page "fausse_page.html" qui d'ailleurs n'existe pas.
Bibliothèques, exemple de jQuery
Les fonctions de JS et surtout celles qui permettent d'accéder au éléments du DOM sont assez limitées. Elles se développent mais pas toujours suffisamment. De plus, on doit faire avec les différences entre Firefox, Chrome, Edge, Safari…
Le plus souvent on préfère utiliser une bibliothèque qui ajoute des fonctionnalités. La plus populaire (de loin) est jQuery. J'ai ajouté jQuery.3.4.1 à page_10.html. Le fichier minifié – c'est une façon spéciale de compresser les fichiers JS – ne pèse même pas 100 ko. Ce n'est rien au regard de tout ce qu'apporte jQuery. Par exemple, dans un site web, s'il y a un beau menu déroulant, vous pouvez être certains que jQuery est utilisé.
Pour illustrer l'utilisation de jQuery, dans page_10.html,
<h2>Des bibliothèques</h2> <!-- page_10.html --> <div class="carre rouge"></div> <div class="carre vert"></div> <div class="carre bleu"></div> <div class="carre rouge"></div> <div class="carre vert"></div> <div class="carre bleu"></div> <div class="carre rouge"></div> <div class="carre vert"></div> <div class="carre bleu"></div> <div class="carre rouge"></div> <div class="carre vert"></div> <div class="carre bleu"></div>
Je veux que chaque carré soit cliquable, c'est à dire que chaque carré soit lié à un événement. Vais-je devoir doré chaque <div> d'un id pour les atteindre depuis le script script_10.js ? Ce serait fastidieux, on préférerait éviter…
// script_10.js
function bouton_couleur(e){
let $item = $(e.target);
if ($item.hasClass("rouge")) {
alert("Ce bouton est rouge");
} else if ($item.hasClass("vert")) {
alert("Ce bouton est vert");
} else {
alert("Ce bouton est bleu");
}
}
$(".carre").click(bouton_couleur)
Ci-dessus, en ligne 13, $ est un raccourci pour désigner jQuery.
Le code $(".carre") permet d'atteindre directement tous les nœuds de la page qui possèdent la classe carre. Ainsi on atteint tous les <div>. Ensuite, on associe à tous ces nœuds l'événement click qui déclenche la fonction bouton_couleur.
En ligne 3, on veut récupérer la cible du clic avec e.target. Mais e.target désigne un nœud ordinaire. En notant $(e.target) on obtient une version augmentée par jQuery qui nous donne accès à des fonctionnalités supplémentaires.
Vous comprenez que de tels outils font gagner en productivité, c'est à dire qu'une simple ligne de code permet de faire beaucoup.
À faire : n'oubliez pas de tester.
