IX. Les liens▲
Sans eux, la toile (Internet) n'existerait pas. En effet, les milliards de référencements de pages permettant de naviguer, de surfer, de butiner au travers de l'immense quantité d'informations diverses et variées, accessibles par chacun pour le meilleur et pour le pire, ne seraient pas possibles. À une échelle plus modeste, au niveau d'un site, le renvoi à une explication donnée dans une autre page est une technique couramment utilisée permettant de mieux structurer un texte tout en offrant au lecteur un moyen simple de revenir sur des connaissances annexes. C'est dire l'importance de ces objets. Bien sûr leur utilisation peut être opérée en HTML pur, mais ce chapitre va nous montrer comment JavaScript complète et accroît les diverses manières de créer de tels objets.
IX-A. Création et définition des liens▲
En JavaScript, tous les liens apparaissant dans une page sont introduits par la balise HTML <A>…</A>. Pour chaque occurrence de ces balises, un objet est créé et tous les liens apparaissant dans une page sont contenus dans un objet links qui est un tableau propriété de l'objet document. On notera le fait que l'on a utilisé le terme introduits et non pas définis. En effet, si un lien peut être directement défini en HTML, il peut aussi n'être qu'introduit puis défini sous JavaScript.
Un lien, qu'il soit totalement défini ou pas, comporte deux parties : la partie opérationnelle qui établit le lien physique recherché et la partie interface (texte, image, zone sensible d'image…) sur laquelle l'utilisateur doit agir pour que la partie opérationnelle soit activée.
Résumons ces deux aspects dans l'exemple suivant. Voici deux liens, le premier matérialisé par un texte, et le second par une image. En outre, le premier est totalement défini, alors que le second va dépendre d'un choix que vous allez devoir faire. Celui-ci ne peut donc pas être figé et JavaScript va nous permettre de répondre à votre choix.
Site du Département d'Informatique de Marseille-Luminy | En cliquant sur l'image ci-dessous, un dialogue vous permettra de choisir entre les trois sites suivants :
|
Regardez la barre d'état en bas de la fenêtre de votre navigateur. Lorsque vous passez le pointeur de souris au-dessus du lien de gauche, l'URL à atteindre s'affiche. Le lien est prédéfini ! À présent, survolez le bouton de choix ; l'URL qui s'affiche est celle de la page courante. En effet, dans le cas où la référence ne peut être résolue à l'appel, autrement dit, si le programme chargé d'affecter la référence renvoie la valeur undefined, la page active le reste. Essayez par exemple de donner un numéro non proposé et regardez ce qui se passe. Un message d'erreur vous signale que la référence n'a pu être résolue, ce qui dénote un site mal géré.
Afin d'éviter le message d'erreur, il vaut mieux prévoir l'éventualité et renvoyer la chaîne "#" qui correspond à l'URL courante. Essayez à nouveau ! C'est mieux, non ?
Voici comment ont été réalisés ces deux types de liens :
- le premier, celui de gauche, est obtenu directement via une balise HTML et a la forme suivante :
- le second, celui de droite, dispose dans sa partie interface d'une image et passe par une fonction pour sa partie fonctionnelle :
<a href
=
""
OnClick
=
"this.href=choix()"
><img src
=
"./images/Choisir.jpg"
width
=
"72"
height
=
"30"
border
=
"0></a>
La fonction choix est de la forme :
function choix
(
){
var Num=
prompt
(<
Message>
);
//Choix de l'utilisateur
switch(
Num){
//Aiguillage selon ce choix
case 1
:
return <
URL 1
>;
case 2
:
return <
URL 2
>;
...
case <
i>
:
return <
URL i>;
...
default
:
return "#"
;
//Renvoi de # si réponse non prévue
}
}
On remarque que l'appel de la fonction ne peut en aucune façon s'opérer tel quel dans href. En effet, celui-ci réclame un argument dont la syntaxe est bien définie et à laquelle ne répond pas l'appel de la fonction. On est donc contraint d'opérer de deux façons possibles :
- Soit préciser en argument de href que l'on va exécuter une séquence JavaScript simplement en faisant précéder celle-ci de javascript :. Ici la séquence se réduirait donc à l'appel de la fonction choix() et on aurait alors :
- Soit, comme on l'a proposé plus haut, passer par la prise en compte d'un événement « click » pour pouvoir affecter une URL au href via cette fonction. Nous reviendrons plus loin sur les événements associés aux liens.
IX-B. Les propriétés des liens▲
Nous avons vu que tous les liens hypertextes contenus dans une page étaient rassemblés dans un tableau links, propriété de l'objet document. Chacun des éléments de ce tableau (i.e. chaque lien hypertexte) est un objet comportant un certain nombre de propriétés que nous allons passer en revue.
Tout d'abord, définissons la syntaxe d'une URL. Celle-ci doit être de la forme :
<protocole>//<nom de domaine>[[:<port>]<chemin d'accès>[?<recherche>][#<ancre>]]
- parmi les protocoles les plus courants : http:, ftp:, mailto:, file:/, news:, gopher:, about:, javascript:, mocha:, où les quatre derniers ont une utilisation spécifique ;
- on appelle <domaine> le couple <nom de domaine>:<port> lorsque ce dernier existe. En son absence, <domaine>=<nom de domaine>. Nous ne nous appesantirons pas sur le champ :<port>, d'une utilisation très marginale et qu'il convient de ne pas mettre entre toutes les mains !;
- le <nom de domaine> correspond à l'adresse du serveur. Lorsque l'URL se limite à la donnée du protocole suivi du nom de domaine, un chemin d'accès implicite vers un fichier cible est prévu : le fichier index.html. En l'absence de ce fichier, le navigateur donne accès à toute la hiérarchie du domaine et en particulier à des fichiers qui théoriquement ne devraient pas être accessibles au client. Ceci est d'ailleurs vrai dans toute la hiérarchie si l'URL n'a pas pour cible un fichier, mais le nom d'un répertoire. C'est la raison pour laquelle, par mesure de sécurité, il convient de prévoir dans chaque répertoire un fichier index.html. Essayez, par exemple d'accéder à l'adresse http://www.dil.univ-mrs.fr/~guizol/Le_Site_JS/Chapitre_IX/ ou tout autre répertoire de mon site… Si je n'ai rien oublié, vous allez toujours trouver un fichier qui vous empêche de musarder chez moi ! Non, mais ! ;
- le champ ?<recherche> se rencontre lorsque vous avez lancé une recherche sur un site. Essayez par exemple de lancer une requête sur un moteur de recherche ;
- enfin, le champ #<ancre> permet d'accéder à l'intérieur d'un fichier cible à un emplacement particulier qui a été prévu par le créateur en positionnant une étiquette.
Par exemple, l'URL : http://www.dil.univ-mrs.fr/~guizol/Le_Site_JS/Chapitre_VI/Chapitre_6.html#SLICE comporte le protocole (http:), le nom de domaine (www.dil.univ-mrs.fr), le chemin d'accès (~guizol/Le_Site_JS/Chapitre_VI/Chapitre_6.html) et une ancre dans ce fichier (#SLICE) qui positionne automatiquement le document sur le paragraphe concerné.
IX-B-1. La propriété hash▲
C'est une propriété accessible en lecture/écriture spécifiant, si elle existe, le nom de l'ancre faisant partie de la cible de l'URL. La chaîne contient le caractère #.
IX-B-2. La propriété host▲
Accessible elle aussi en lecture/écriture, cette propriété permet de spécifier l'ensemble nom de domaine + port.
IX-B-3. La propriété hostname▲
Alors que la précédente concernait l'association nom de domaine/port, celle-ci, accessible en lecture/écriture, ne s'intéresse qu'au nom de domaine.
IX-B-4. La propriété href▲
IX-B-5. La propriété pathname▲
Le pathname concerne la cible à atteindre sur le serveur désigné par le nom de domaine. On a vu que cette cible pouvait être soit un fichier, soit un répertoire et dans ce cas le chemin d'accès était complété par index.html. Si ce fichier existe, c'est lui qui est chargé, sinon, le navigateur affiche le contenu du répertoire et à partir de lui, l'arborescence du site. Cette propriété est à nouveau accessible en lecture/écriture.
IX-B-6. La propriété port▲
De la même façon que la propriété hostname s'intéresse à la partie nom de domaine de la propriété host, la propriété port spécifie le port de communication de l'URL.
IX-B-7. La propriété protocol▲
Cette propriété de lien accessible en lecture/écriture permet de spécifier le type de protocole utilisé pour accéder à la cible désignée par le lien.
IX-B-8. La propriété search▲
Cette portion de l'URL permet de faire transiter une liste de couples nom/valeur introduite par le signe ? résultant d'une requête. Cette liste sera interprétée selon le même mode que les cookies que nous verrons plus loin.
Par exemple, pour http://www.google.fr/search?q=javascript&hl=fr&btnG=Recherche on procédera tout d'abord à l'extraction de la zone search, puis des différents couples en utilisant la méthode split paramétrée par le séparateur des couples (ici, '&') et enfin, pour chacun d'eux, le nom et la valeur en appliquant à nouveau la méthode splitLa-méthode-split() paramétrée par le séparateur '=';
Cette propriété est encore accessible en lecture/écriture.
IX-B-9. La propriété target▲
Cette propriété permet de spécifier la fenêtre dans laquelle sera chargée la page désignée par le lien. La valeur qui lui est affectée peut être une valeur prédéfinie : "_blank" qui opère le chargement dans une nouvelle page, "_self", valeur par défaut qui conduit à charger la nouvelle page dans la fenêtre contenant le lien, "_parent" qui charge la page référencée dans le cadre (frame) immédiatement supérieur à celui contenant le lien supprimant ainsi tous les cadres de même niveau que celui de départ, et enfin "_top" qui place la page chargée au plus au niveau, occupant ainsi toute la fenêtre du navigateur et supprimant du même coup tous les cadres qu'elle contenait.
Par ailleurs, target peut être affecté avec un nom correspondant à celui qui a été donné à une fenêtre préalablement ouverte par la méthode window.open(<url>,<NOM DE FENÊTRE>,<caractéristiques>) ou celui d'un cadre défini dans la page courante. Si aucune fenêtre (ou cadre) désignée par le nom précisé n'existe, le navigateur se comporte comme si target avait été affecté à "_blank".
IX-B-10. La propriété text▲
Cette propriété permet de spécifier le texte utilisé pour la partie interface du lien, le texte contenu entre les balises <A> et </A> qui sera visible sur la page. Cette propriété est seulement accessible sous Netscape. Toutefois, du fait que les objets liens héritent des propriétés d'éléments HTML, Internet Explorer permet non seulement d'obtenir le texte en utilisant la propriété innerText, mais aussi l'environnement HTML propre à ce texte grâce à la propriété innerHTML.
IX-B-11. Les propriétés x et y▲
IX-C. La propriété location de l'objet window▲
Nous venons de voir les propriétés d'un objet de type lien, élément du tableau links, lui-même propriété de l'objet document. L'objet window dispose d'une propriété, location, elle-même comportant la plupart des propriétés que nous venons de voir : hash, host, hostname, href, pathname, port, protocol, et search. Pourquoi avoir créé deux entités aussi ressemblantes ? En fait, elles ne s'intéressent pas aux mêmes objets ! Alors que la première, nous venons de le voir, s'applique à TOUS les liens hypertextes apparaissant dans une page, la seconde, elle, représente l'adresse de la page courante affichée dans la fenêtre du navigateur.
Cette propriété peut être modifiée. Ainsi, si l'on affecte à location ou location.href une nouvelle adresse, la page correspondante va être chargée dans la fenêtre courante et donc se substituer à la page actuellement affichée (c'est une autre façon d'opérer un lien par programme). On peut aussi ne modifier qu'une propriété de location. Par exemple, pour se déplacer dans une page sans la recharger, on va seulement affecter location.hash.
Essai location.hash="hash"
Alors qu'Internet Explorer effectivement ne fait que se déplacer dans la page, Netscape, pour ses versions 2 et 4.5 (au moins) recharge la page !
Alors qu'en lecture, la propriété hash associe le caractère « # » à l'étiquette choisie, comme cela apparaît dans l'exemple précédent, il ne faut pas mentionner ce caractère en écriture !
De la même façon, en modifiant la propriété search, vous pouvez forcer le navigateur à recharger l'URL avec une nouvelle requête, ce qui donnera vraisemblablement une apparence différente du document.
location dispose en outre de deux méthodes que nous allons présenter : reload() et replace().
IX-C-1. La méthode reload()([<obligatoire>])▲
Cette méthode comporte un argument facultatif booléen. En l'absence d'argument ou si celui-ci a la valeur false, cette méthode agit exactement comme si l'utilisateur cliquait sur le bouton « Actualiser » du navigateur. Si la page a été modifiée sur le serveur depuis le précédent chargement, elle est de nouveau chargée depuis ce dernier, sinon, elle est rechargée depuis le cache.
Si l'argument a la valeur true, la page est systématiquement rechargée depuis le serveur.
IX-C-2. La méthode replace()(<URL>)▲
Cette méthode permet de remplacer l'URL affichée dans la fenêtre du navigateur par l'URL fournie en paramètre. Si la fonction se limite à cela, quelle différence avec la solution d'affecter location avec la nouvelle URL ?
En fait, alors que dans la seconde solution, l'URL précédente demeure dans l'historique de navigation, pouvant ainsi être de nouveau atteinte en cliquant sur le bouton « Précédente » du navigateur, avec la méthode replace(), la substitution est totale ; non seulement dans la fenêtre, mais aussi dans l'historique ! Ainsi l'URL précédente n'est plus accessible par le bouton « Précédente ».
IX-D. Les événements associés▲
Les événements que nous allons passer en revue ne sont pas spécifiques des liens, mais a contrario, ceux-ci peuvent faire usage de ceux-là de diverses manières et en particulier pour animer des textes ou des boutons commandant l'activation de liens ou tout simplement, comme nous l'avons vu au début de ce chapitre dissimuler derrière l'interface d'un lien un aiguillage vers une URL finale choisie par l'utilisateur. Ce ne sont là que quelques exemples qui n'ont pas la prétention de couvrir l'ensemble des possibilités et nous laisserons libre cours à l'imagination du lecteur pour trouver des utilisations judicieuses de ces outils.
De façon générale, tous ces événements apparaîtront dans la définition du lien (entre les balises <A> et </A>) sous la forme :<événement>="<action>" où l'action correspond en fait à des instructions JavaScript.
Ajoutons enfin que les trois premiers que nous allons présenter sont accessibles en tant que propriétés d'un objet de type lien.
IX-D-1. L'événement-propriété OnClick▲
Dès l'apparition de l'événement OnClick, l'action JavaScript qui lui est liée est exécutée, avant même que la valeur associée à href soit considérée. Ce n'est qu'après avoir exécuté l'action liée à l'événement que le navigateur va charger prendre en compte href. Si celui-ci spécifie une URL, la page correspondante va être chargée dans la fenêtre ; si par contre sa valeur est null (si par exemple on a <a href=""… >) une erreur va être signalée selon laquelle l'URL ne peut être trouvée. Afin d'éviter ce problème, ou plus généralement, si l'exécution de l'action fait que l'on veut renoncer à considérer la valeur de href (même si celle-ci est définie), il suffit que l'action associée à OnClick retourne la valeur booléenne false.
Voici un exemple utilisant deux liens dont la définition est totalement identique hormis le fait que seule l'action du second renvoie la valeur false :
Définition du lien | Le lien |
---|---|
<a href="http://www.dil.univ-mrs.fr" OnClick="alert('L\'action associée a OnClick est : '+this.onclick)" target="_blank">Onclick sans false</a> | Onclick sans false |
<a href="http://www.dil.univ-mrs.fr" OnClick="alert('L\'action associée a OnClick est : '+this.onclick);return false" target="_blank"> Onclick avec false</a> | Onclick avec false |
IX-D-2. L'événement-propriété OnMouseOver▲
Cet événement apparaît dès que le pointeur de souris survole un lien. Vous en avez sûrement déjà vu les effets à maintes reprises. En effet, l'action par défaut prévu dans tous les navigateurs consiste à afficher dans la barre d'état, au bas de la fenêtre, l'URL correspondant au lien survolé. Par exemple, passez la souris au-dessus d'un quelconque des deux liens ci-dessus. Vous voyez apparaître "http://www.univ-mrs.fr" correspondant à la valeur de href.
À présent, survolez le lien ci-contre : essai1 de OnMouseOver.
Dans tous les cas, vous voyez apparaître un calque. Cette apparition est le résultat d'une des actions associées à l'événement en question. De plus, si votre navigateur est Explorer vous voyez dans la barre d'état non plus l'URL du lien, ce qui est le fonctionnement normal par défaut du navigateur, mais un message indiquant, par exemple, la fonction associée à l'événement (mais vous auriez pu tout aussi bien afficher l'âge du capitaine…). Dans Netscape, par contre, il n'y a aucun changement dans la barre d'état.
Recommençons l'expérience avec ce second lien : essai de OnMouseOver.
Le fonctionnement est identique au précédent pour ce qui concerne Explorer. Par contre, sous Netscape, nous voyons cette fois apparaître dans la barre de menu, non pas l'URL, mais le message choisi. La seule différence qu'il y a entre le premier et le second exemple est que nous avons retourné de l'action associée à l'événement OnMouseOver, un booléen de valeur true. Cela impose au navigateur de ne pas effectuer l'action par défaut qui consiste à afficher l'URL.
Pourquoi doit-on renvoyer false dans OnClick et true dans OnMouseOver pour forcer le navigateur à faire seulement ce que nous voulons ? Ne cherchez pas à comprendre pourquoi… C'est un héritage du passé !
IX-D-3. L'événement-propriété OnMouseOut▲
Les exemples précédents ont montré, au travers des actions prévues, que l'on pouvait faire apparaître des objets. On a vu que Netscape efface le contenu de la barre d'état dès lors que le pointeur de souris ne survole plus le lien, ce qui n'est pas le cas pour Explorer. Pour cela, Netscape capte, en fait, l'événement OnMouseOut. Il suffit que nous fassions de même pour rendre invisibles les calques ou effacer la barre d'état sous Explorer.
Faisons l'essai : essai de OnMouseOut.
Effectivement, les textes et objets apparaissant lorsque le pointeur survole le lien disparaissent dès que ce n'est plus le cas.
Vous survolez ce lien.
Vous survolez cet autre lien.
Vous survolez encore un lien.
IX-D-4. L'événement OnMouseDown▲
Cet événement apparaît à l'instant précis où le bouton de souris est appuyé et disparaît dès qu'il est relâché. Cela autorise une intervention supplémentaire pendant l'action du clic. En fait celui-ci est décomposé en deux phases, bouton appuyé/bouton relâché.
Pour appliquer cette nouvelle fonctionnalité, considérons un « bouton » ayant trois apparences : un état de repos, un état pointé et un état appuyé ces trois états étant respectivement représentés par les images suivantes :
Repos | Pointé | Appuyé |
---|---|---|
Ces trois images seront utilisées de la façon suivante :
- la première sera celle contenue dans le lien en tant qu'interface par défaut ;
- la seconde se substituera à la première sur événement OnMouseOver, la précédente reprenant sa place sur événement OnMouseOut ;
- enfin, la troisième apparaîtra lorsque le bouton de souris sera appuyé, sur événement OnMouseDown.
Et voilà le travail... ce lienLes-propriétés-et-méthodes-associées-aux-chaînes vous conduira vers une utilisation de cette technique dans le chapitre VII.
IX-D-5. L'événement OnMouseUp▲
Ce dernier événement permet de prendre en compte le fait que le bouton de souris est relâché. Dans l'exemple précédent, sur événement OnMouseUp, nous avons rétabli l'image correspondant à l'état de repos. Si tel n'avait pas été le cas, l'image correspondant au bouton appuyé aurait été maintenue. Dans la réalisation du chapitre VII à laquelle on accède par le lien ci-dessus, vous pouvez voir que l'événement OnMouseOver n'a pas été géré (rien ne se passe lorsqu'on survole le bouton). Par contre, on peut voir que l'événement OnMouseDown provoque une modification de l'allure du bouton et l'événement OnMouseUp permet de faire apparaître le schéma explicatif animé.
Avant de terminer, signalons la propriété referrer de l'objet document qui fait référence à l'URL du document (s'il existe) à partir duquel le document présent a été atteint. Par exemple, vous êtes parvenu à cette page à partir de…
cette URL.Bien entendu, cette propriété n'est accessible qu'en lecture… «On ne peut refaire l'histoire».