ID
a-t-il déjà été évoqué, a priori oui
pour le CSS addEventlistener
et removeEventListener
qui sont introduites dans la suite
s'appellent attachEvent
et detachEvent
pour
Internet Explorer.
La langage Javascript offre la possibilité de manipuler une page
HTML. Il est possible par l'exécution de code Javascript d'agir
directement sur une page affichée par un navigateur et de la
modifier dynamiquement. Il s'agit en fait d'agir sur les données qui
représentent les contenus de la page. Vous savez maintenant qu'une
page HTML respecte une syntaxe précise et qu'elle est composée
d'éléments structurés par des balises. Chacun des éléments qui
apparaît dans la page peut être représenté par une donnée
Javascript. Nous avons déjà rencontré la
donnée document
qui représente le document dans son
ensemble. Javascript propose le type Element
qui
représente les éléments au sein d'une page HTML, c'est-à-dire les
blocs correspondant à des balises, et offre des fonctionnalités pour
les manipuler. On peut ainsi définir une variable représentant un
élément <img>
, un titre <h2>
,
un paragraphe <p>
, un bloc
<div>
, etc., et manipuler ces
variables. Par exemple, il est possible de modifier l'apparence ou
le contenu d'un élément. Ces opérations permettent de créer des
effets dynamiques qui enrichissent les possibilités offertes par
l'usage du seul couple HTML/CSS .
La première méthode d'accès aux données représentant un élément de
la page HTML que nous allons utiliser consiste à exploiter la
possibilité de nommer en HTML un élément de la page grâce à
l'attribut id
(on pourra parler d'élément
identifié). En effet la fonction getElementById
qui s'applique sur la donnée document
permet de
récupérer la donnée de type Element
dont
l'attribut id
correspond à la valeur passée en
paramètre de l'appel de fonction.
Ainsi considérons la portion de code HTML suivante :
<h1> Un exemple avec des id </h1> <div> Un premier bloc div </div> <div id="important"> Ceci est un texte important. </div> <img id="monImage" class="encadree" src="exemple.png"></img>
Il est possible d'associer une variable Javascript pour chacun des
éléments identifiés par un attribut id
de la manière
suivante :
var divImportant = document.getElementById("important"); var lImage = document.getElementById("monImage");
Les éléments qui ne possèdent pas d'attribut id
ne sont
pas accessibles par cette méthode.
document.writeln
dès lors qu'il s'agira de
manipuler dynamiquement des éléments de la page.
L'interaction sur des éléments d'une page nécessite d'aborder des
manipulations un peu différentes de celles étudiées jusque
maintenant.
L'approche à adopter va différer de ce que nous faisions jusque
maintenant car nous agissions sur le contenu de la page au moment
de son chargement. Ainsi les document.writeln
utilisées
étaient interprétées par la navigateur au fur et à mesure de la mise
en place de la construction des éléments comme nous avons
pu l'observer lors du chargement de la page affichant les
momuments. Cela ne convient plus pour ce que nous voulons faire maintenant.
Enfonçons les portes ouvertes : pour agir sur les éléments d'une
page il faut que ces éléments existent... Il faut donc que la page
ait été chargée complètement par le navigateur. Les traitements
agissent donc sur une page déjà "existante". Il faut donc trouver un
moyen pour déclencher ces traitements alors que la page a fini d'être
chargée. Cela est possible grâce à
la programmation événementielle.
On appelle événement :
Le principe est de permettre le déclenchement d'un traitement lorsqu'un événement particulier se produit sur un élément de la page. Il existe différents types d'événements. Ils caractérisent l'action réalisée et dépendent de l'élément sur lequel porte l'action, tous les types d'événements ne sont pas disponibles pour toutes les sortes d'éléments. Chaque type d'événement à un nom :
click
est déclenché lors d'un clic sourisload
est déclenché à la fin du chargement
d'un élémentmouseover
est déclenché lorsque la
souris passe au-dessus d'un élémentkeypress
est déclenché lors de l'appui
d'une touchechange
est déclenché lorsque le
contenu d'un élément change,
La liaison d'une fonction à un événement pour un élément donnée se
réalise grâce à la fonction addEventListener
du
type Element
:
La syntaxe d'un appel sur un élément ressemble donc à :
element.addEventListener(typeEvenement,fonctionDeclenchee)
On rencontrera (et utilisera) donc souvent le schéma typique de code
suivant, où action
est une fonction supposée définie par
ailleurs :
var unElement = document.getElementById("lElementQueJeVeux"); unElement.addEventListener("click",action);
qui aura pour conséquence que la méthode action
sera
appelée à chaque fois que l'utilisateur cliquera sur l'élément de la
page dont l'id
est lElementQueJeVeux
.
addEventListener
est un nom de fonction
(identificateur) et pas une
chaîne de caractères représentant ce nom.
On utilise le terme d'abonnement de la fonction à l'événement sur l'objet. La fonction est elle appelée fonction écouteur, listener en anglais.
Il nous reste une petite difficulté technique à franchir pour pouvoir exploiter ces événements sur les éléments de notre page mais elle n'est pas très compliquée à comprendre et facile à résoudre avec un peu de méthode. Et les exemples clarifieront tout cela.
Ce "problème" concerne la mise en place des abonnements pour ces événements. On retrouve un problème similaire à celui rencontré précédemment : pour réaliser un abonnement il est nécessaire de disposer de la donnée le représentant. Il faut donc que cet élément existe. On ne peut donc pas réaliser l'abonnement tant que la page n'a pas été chargée par le navigateur. Or le code Javascript est a priori exécuté pendant le chargement de la page, pas après...
Pour résoudre ce paradoxe apparant nous allons utiliser le
mécanisme événementiel et un événement en particulier :
l'événement load
qui permet de déclencher un appel de
fonction (donc un traitement) après qu'un élément ait été
complètement chargé.
Il faut créer une fonction qui réalise tous les
abonnements et abonner cette fonction à
l'élément window
, qui est l'élément qui représente la
page dans son ensemble, pour l'événement load
. Ainsi la
mise en place des abonnements sera réalisée après que la page ait
été chargée, on a donc l'assurance que les éléments impliqués existent.
Passons à la pratique, il "suffit" de suivre étape par étape la démarche suivante :
mesEvenements.js
,
head
du document HTML concerné
le lien vers ce fichier de scriptaction
précédemment,
setupEvents
qui aura pour responsabilité de
mettre en place les abonnements souhaités en respectant le schéma
type vu ci-dessus,window
pour l'événement load
Le fichier mesEvenements.js
ressemblera donc à ceci
:
/* fonction de mise en place des abonnements */ var setupEvents = function () { // abonnement de la fonction action pour l'élément d'id lElementQueJeVeux en réaction à un click var unElement = document.getElementById("lElementQueJeVeux"); unElement.addEventListener("click",action); // ... on répète le même schéma ici si on veut mettre en place d'autres abonnements } // pour appeler la fonction ci-dessus quans la page est chargée window.addEventListener("load",setupEvents); // ---------------------------------------- /* Documentation de la fonction action */ var action = function () { ... // ce que action doit faire } // ... et d'autres définitions éventuellement
alors que le fichier HTML ressemble à :
<html ...> <head> <script type="text/javascript" src="mesEvenements.js"></script> ... </head> <body> ... <div id="lElementQueJeVeux"> ... </div> ... </body> </html>
alert
qui s'applique à la
donnée window
permet l'affichage d'une
fenêtre pop-up affichant le message passé en paramètre (de type
String
).
window.alert
) s'affiche dès que l'on passe la
souris sur l'image, le type de l'événement
est mouseover
. setupEvents
window.addEventListener("load",
setupEvents);
action1
et celle que vous avez créée).Sur un élément donné on peut avoir
mousedown
est déclenché lorsque l'on
presse le bouton de la souris et l'événement mouseup
lorsqu'on le relâche. Complétez le code Javascript de l'exemple pour
afficher une alerte différente lorsque chacun de ces événements se
produit sur l'image.click
sur l'élément d'id
"piedDePage
" qui
déclenchera la fonction suivante :
var piedEnBleu = function() { var piedDePage = document.getElementById("piedDePage"); piedDePage.style.backgroundColor = "blue"; piedDePage.style.color = "white"; }
La dernière Manip a permis de mettre en œuvre une première
interaction avec la page : le clic sur la zone
appelée piedDePage
a provoqué sont changement de
couleur. Le code est assez simple à comprendre : on constate que
les données de type Element
dispose d'une
propriété style
qui représente les informations sur
l'apparence de l'élément. Informations elles-mêmes caractérisées par
des propriétés telles que backgroundColor
et color
qui ne sont pas sans rappeler celles des
feuilles CSS auxquelles elles ne sont bien sûr pas étrangères malgré
quelques différences de nommage.
On eut ainsi accéder ou modifier une valeur de style d'un élément
présent dans la page. Le navigateur interprétant en continu toute
modification de la page on obtient des effets dynamiques. Pour
modifier le style d’un élément ayant
comme id
monElement et donner la
valeur laValeur à sa propriété laPropriete il faut
utiliser la syntaxe suivante :
var monElement = document.getElementById(monElement); monElement.style.laPropriete = "laValeur";
On note que les valeurs des propriétés sont des chaînes de caractères.
div
d'identifiant zoneTravail
et
une feuille CSS qui définit pour cette balise un texte de
couleur red
et une couleur de
fond #EEEEEE
.blue
et la couleur de
fond yellow
.div
et ajoutez dans le code Javascript pour
qu'un clic sur ce nouvel élément permette de modifier
l'élément zoneTravail
en lui attribuant la couleur de
texte black
, la couleur de fond #77FF77
et une bordure d'épaisseur 2px, en trait plein et de
couleur #00FF00
.div
et
le Javascript pour que cette fois, un clic sur l'élément ajouté
provoque l'inversion des couleurs de texte et de fond
de zoneTravail
, quelles que soient ces couleurs.border-radius:6px;
sur le style de vos éléments de type
bouton. Vous trouverez peut-être que cela accroit le "look bouton".
Math.random
,
écrivez sa spécification.Math.floor
. mouseover
est déclenché dans un tel cas.
D'autres propriétés existent sur les données de type Element
,
leur présentation exhaustive serait fastidieuse. Nous les présenterons au fur
et à mesure des besoins. Elles correspondent pour une
bonne partie d'entre elles aux propriétés des éléments HTML qu'elles
représentent.
Prenons l'exemple des images, en HTML la balise img
dispose
d'un attribut src
qui désigne le fichier contenant la définition
de l'image à afficher. Et bien, si une donnée Javascript représente un
élément img
, il dispose alors d'une propriété src
et il est possible de modifier cette valeur ce qui entraine une modification
de l'image dans la page !
Ainsi si dans une page une balise img
a pour
identifiant monImage
, le code Javascript
suivant :
var elementImg = document.getElementById("monImage"); elementImg.src = "isn.png";
aura pour conséquence que dans la page HTML, l'image correspondant au
fichier isn.png
sera affichée dans
l'élément monImage
, quelle que soit l'image initialement présente
(éventuellement aucune).
img
et trois éléments "cliquables" ("boutons"),
telle qu'initialement aucune image ne soit affichée. On associe
un fichier image à chaque "bouton" et le clic sur un bouton
provoque l'affichage de l'image dans la zone img
de
la page.
300px
(par exemple).
Autre exemple, les éléments de type input
dispose
d'une propriété value
qui correspond au texte (de
type String
) contenu dans ce champ de saisie. Il est
donc possible de lire ou de modifier le contenu de ce champ.
change
est déclenché à chaque fois que
la valeur d'un élément input
est modifiée par
l'utilisateur (l'événement est activé lorsque l'on "quitte"
l'élément input
- on dit qu'il perd le focus). En
partant du travail réalisé lors la Manip sur la conversion de
température, ajoutez à ce document le code Javascript qui permet,
lors d'une saisie (numérique, on ne s'occupera pas pour
l'instant de ce qui se passe dans un autre cas) dans un champ, à la
valeur correspondante pour l'autre unité de mesure de s'afficher dans
l'autre champ.
Il est également possible de manipuler le contenu "complet" d'un
élément, c'est-à-dire le code HTML qui se trouve entre les balises
ouvrante et fermante de cet élément. Ce contenu est identifié par la
propriété innerHTML
. En changeant sa valeur, on modifie
la portion de la page correspondante. La valeur de cette propriété est
une chaîne de caractères représentant du code HTML. On peut donc y
placer des balises, elles seront interprétées.
innerHTML
la valeur :
le contenu a <b>été</b> changé. On peut placer dans <b>innerHTML</b> de l'HTML qui est interprété. Du <b>gras</b> ou une image par exemple : <br/> <img src="alan-turing.jpeg" alt="Alan Turing">
la température ccc en
Celsius vaut fff en Fahrenheit
.Une même fonction peut être utilisée pour plusieurs abonnements.
div
identifiés. display: none;et pour le second le couple
display: block;(cette seconde valeur est la valeur par défaut pour les blocs
div
)
div
identifiés et cette
fois attribuez au premier la propriété :
visibility: hidden;et au second
visibility: visible;(cette seconde valeur est la valeur par défaut pour les éléments).
display
et visibility
?txtcache
lorsque l'on clique sur
le "bouton" Montrer et de le masquer avec le
bouton Cacher. Faites une première version en jouant sur
l'attribut display
et une seconde pour
l'attribut visibility
.
Il est possible de désabonner une fonction d'un événement. Cela se
réalise à l'aide de la
fonction removeEventListener
. Dans la mesure où il peut
y avoir plusieurs abonnements pour une même fonction et plusieurs
fonctions pour un même abonnement il est nécessaire de préciser à la
fois le type de l'événement et la fonction désabonnée. La
syntaxe d'un désabonnement est donc :
element.removeEventListener(typeEvenement,fonctionDeclenchee)
div
identifié, telle que
img
dont le contenu
passe à chaque fois que l'on clique dessus d'une image à l'autre.