Puce et Média

Recherche et développement en multimédia

  • Augmenter la taille
  • Taille par défaut
  • Diminuer la taille
Puce et Média > AJAX > Le DOM Scripting

Le DOM Scripting

Envoyer Imprimer PDF

DOM_scriptingPourquoi DOM Scripting ?

Dans un premier temps, si d'une part, le mot DOM n'évoque rien pour vous, vous pouvez suivre le tutorial proposant une rapide introduction au DOM et d'autre part, pour l'aspect scripting vous pouvez suivre celui qui aborde les bases de JavaScript.

Nous allons explorer au cours du présent tutorial les avantages et parfois les complexités du DOM Scripting. Avant d'aller plus loin, voyons voir une définition succinte de ce qu'est le DOM Scripting, ou de ce qu'il y a quelques années, on appelait le DHTML.

Le DOM Scripting est une technique qui permet de manipuler le DOM d'une page web avec le langage de programmation ECMAScript. De ce fait, tout se passe côté client et décharge ainsi le travail côté serveur.

L'interface utilisateur des applications peut donc être très souple à utiliser, avoir une ergonomie totalement adaptative et évolutive et permettre ainsi à l'utilisateur, une expérience plus riche :

Les fenêtres déplaçables au sein d'une page, la réorganisation du contenu, le réagencement de certaines données... mais si on couple ces interactions avec la gestion CSS de l'affichage, d'autres portes encore plus esthétiques s'ouvrent alors, et permettent des effets visuels de transitions ou de présentations comme les menus à onglets, les accordéons, les fenêtres compilables, etc...

On serait tenté de penser que le DOM Scripting contient l'aspect AJAX dont nous présentions les possibilités dans la première partie de ce tutorial. En fait, cela est un peu vrai, rappelons nous que AJAX est un avant tout un ensemble de technologies dont DOM, ECMAScript et CSS font partie.

Ce qu'il manque à la description faite ci-dessus est le noyau dur de AJAX, c'est à dire le rechargement de données sans recharger la page, l'objet XMLHttpRequest.

Explorons le DOM - Description et mise en place de la structure

Commençons par utiliser un simple document HTML contenant quelques balises et différents attributs. Téléchargez le document dom_scripting_01.htm puis explorez en le code HTML.

La structure est assez classique, trois divisions #contenu, #menu et #commande qui contiennent des balises classiques de type h2, p, et img. Notez au passage l'utilisation de quelques balises éparses de type strong, acronym ainsi qu'une table. Enfin une feuille de style, dom_script_01.css est attachée uniquement afin de positionner les trois div sur la page.

Nous allons mettre en place une mécanique Javascript qui va nous permettre d'explorer le code HTML de la page, soit en utilisant getElementById, soit getElementsByName, ou encore getElementsByTagName. L'ensemble de cette mécanique va se placer dans la div #commande et va être constituée de deux parties, la zone de recherche et la zone de résultats.

Zone de recherche

Pour cette zone, en dehors du titre, nous avons besoin d'un champ de saisie (saisie), d'un menu déroulant pour indiquer le type d'action (mode) et d'un bouton de validation (envoi). Les diverses valeurs nécessaires au menu déroulant sont : aucun, id, name et tag, ayant comme étiquette et valeur la même identification. Enfin, le bouton doit pointer vers une fonction javascript afficheInfos(); qui nous permettra de donner sens à cette mécanique.

<h3>Recherche</h3>
<input id="saisie" name="saisie" type="text" />
<select id="mode" name="mode">
<option value="aucun" selected="selected">aucun</option>
<option value="id">id</option>
<option value="name">name</option>
<option value="tag">tag</option>
</select>
<input id="envoi" name="envoi" type="button" onclick="afficheInfos();" value="Bouton"/>

Zone de résultats

La zone de résultats est bien plus réduite que la première. Il n'est besoin qu'un d'un titre et d'un champ de texte (sortie) pour afficher les données renvoyées par la fonction.

 <h3>Résultats</h3>
<textarea id="sortie" name="sortie" cols="100" rows="6"></textarea>

Mise en place de la mécanique

Fonctions de renvoi

Plaçons un script directement dans l'entête du document, pour cela rien de plus simple ouvrons un jeu de balise <script> ayant pour type text/ecmascript. Et déclarons y la fonction afficheInfos(). Déclaration et initialisation de la fonction dans l'entête de la page :

<script type="text/ecmascript">
function afficheInfos(){
}
</script>

Une fois la fonction déclarée, nous allons dans un premier temps, récupérer les données saisies par l'utilisateur, à savoir celles du champ saisie, et celles du menu déroulant mode, pour les stocker respectivement dans les variables saisie et mode.

Ensuite, initialisons une variable sortie qui recevra plus tard le résultat à afficher. Pour cela, rien de plus simple, grâce au DOM qui nous permet de cibler et manipuler directement les éléments que l'on souhaite. Ajoutons donc les quelques lignes qui suivent :

var saisie = document.getElementById('saisie').value;
var mode = document.getElementById('mode').value
var sortie = null

Filtrage des données reçues

En fonction du mode sélectionné, à savoir id, name ou tag, le filtrage des données devra utiliser respectivement la méthode getElementById(saisie), getElementsByName(saisie) ou getElementsByTagName(saisie) appliqué à document.

Chacune de ces méthodes va nous renvoyer une structure différente qu'il nous faudra donc exploiter de manière différente. Utilisons une imbrication switch() qui est bien appropriée pour ce genre de filtrage.

La première nous renvoie forcément un seul objet, qui est de type [object HTML...Element]. Si nous souhaitons en extraire son contenu, il nous faut alors faire référence au premier enfant (firstChild) de cet élément pour en atteindre le nodeValue. Rappellez vous, les éléments texte sont contenus dans un noeud de type texte.

La seconde peut être source de confusion. En effet, l'utilisation de l'attribut name n'est pas reconnue dans Internet Explorer, et si vous testez avec ce navigateur en utilisant getElementsByName(name), la fonction recherchera en fait sur un attribut id équivalent et non sur un attribut name équivalent.

De ce fait il peut être judicieux de bâtir ces références sur des id uniquement (si la recherche doit s'effectuer sur ce type de référence), voir à ce sujet la note de Jeremy Keith à propos de son livre DOM Scripting paru avant la sortie de IE 7.

Une autre remarque propre à cet exemple si vous testez sur Firefox :

Tapez 'presentation' en recherche par name, seul la balise <p name="presentation"> sera concernée, recherchez cette balise dans le code pour la visualiser.

Si alors vous récupérez firstChild.nodeValue uniquement, vous ne récupérerez que la partie de la phrase jusqu'à rencontrer la balise acronym, qui en fait, est le second noeud enfant de la balise p. De ce fait, afin de récupérer l'intégralité du contenu de la balise, il faut travailler sur la propriété innerHTML ou mettre en place une mécanique de récupération plus avancée.

Enfin, la troisième fonction, nous retourne un objet contenant la liste des divers noeuds intérogés. Contentons nous d'en extraire la quantité. Voyons ainsi combien de balise X sont utilisées dans le document.

Affichage du résultat

Prévoyons uniquement une valeur par défaut dans la structure switch(), qui s'assurera qu'un mode ait bien été sélectionné par l'utilisateur avant de lancer sa requête. Une fois la sortie définie en fonction du mode choisi, il ne reste plus qu'à l'injecter dans le champ sortie prévu à cet effet. Nous pouvons encore une fois utiliser directement la propriété value du fait que nous utilisons un champ de formulaire comme panneau d'affichage.

switch(mode){
case "id":
sortie = "Il s'agit d'une balise "
sortie += document.getElementById(saisie).nodeName
sortie += " qui contient " + document.getElementById(saisie).firstChild.nodeValue
break;
case "name":
sortie = "Il s'agit d'une balise "
sortie += document.getElementsByName(saisie)[0].nodeName
//resultat += " qui contient " + document.getElementsByName(saisie)[0].firstChild.nodeValue
sortie += " qui contient " + document.getElementsByName(saisie)[0].innerHTML
break;
case "tag":
sortie = "il existe "
sortie += document.getElementsByTagName(saisie).length
sortie += " instances de la balise " + saisie
break;
default:
alert("Veuillez sélectionnez un mode");
}
document.getElementById('sortie').value = sortie

Recomposer et manipuler le DOM

Dans cette première partie du tutorial sur le DOM Scripting, nous avons exploré de manière statique le DOM. Nous allons à présent écrire des parties inexistantes du DOM. Imaginons une page web classique composé de balises <abbr> et/ou <acronym>. Bien souvent l'utilisateur n'en connait pas le sens réel. Il serait bien de donner des informations sur les sigles qu'ils représentent. Cela serait une information riche et intéressante.

C'est un travail qui peut être à la charge du navigateur en délestant donc le travail réalisé côté serveur. Inspiré d'un exemple du livre de Jeremy Keith, nous allons recréer à la volée cette partie manquante du document. Voir également l'excellent article de Lars Holst au sujet des deux balises accr et acronym.

Mode opératoire

L'idée est de placer une liste de définitions (<dl>) au sein d'une balise <div id="menu">, les deux créées à la volée. Cette liste de définitions contiendra chaque acronyme sous forme de paire <dt>, <dd>, avec <dt> --> pour l'acronyme, et <dd> --> pour la définition.

Afin d'agrémenter le tout, nous pouvons placer une balise de tête de niveau <h2> qui nous servira de titre pour présenter la liste de définition. Nous pourrions également placer une interaction sur cette barre de titre, pour manipuler la fenêtre, gestion accordéon, glissé déposé, ou tout autre fonctionalité interactive.

De même, à la fin de la liste de définition, il pourrait être ajouté une balise holder, afin de permettre l'ancrage d'un CSS qui permettrait un décor plus avancé et une gestion de l'extensibilité de la fenêtre.

Mise en place du fichier et l'appel à la fonction

Commençons par charger le document HTML dom_scripting_02.htm et sa feuille de style dom_script.css . Puis, lions lui un fichier Javascript externe dom_scripting_02.js qui nous servira de mécanisme de construction. L'appel de la fonction se fait depuis le bouton présent dans la page.

Liaison dans l'entête du document HTML du fichier Javascript externe
<head>
...
<script type="text/ecmascript" src="/dom_scripting_02.js"></script>
...
</head>
Appel de la fonction depuis le bouton
<div id="commande">
...
<input id="envoi" name="envoi" type="button" onclick="afficheInfos();" value="Bouton"/>
</div>

Fichier Javascript externe

Initialisation

Dans un premier temps, il est nécessaire de récupérer une liste de toutes les balises <acronym> présentes sur la page et de les stocker dans une variable. La réutilisation en sera ensuite facilitée.

function afficheInfos() {   
var acronym = document.getElementsByTagName("acronym");
...
}
Boucle sur l'ensemble des acronymes

Premier point, créer une liste de définitions stockées dans une variable dl, avant d'itérer la boucle, ceci afin de pouvoir stocker les paires dt, dd au fur et à mesure.

Mettons ensuite en place la boucle qui va itérer sur l'ensemble des balises. Nous récupèrons à chaque fois les informations contenues dans l'attribut title dans le noeud lui même, que nous plaçons respectivement dans des variables temporaires def_temp et acronym_temp. L'attribut title contenant la définition de l'acronyme et le noeud contenant l'acronyme lui même.

var dl = document.createElement("dl");
for (var i=0; i<acronym.length; i++) {
var def_temp = acronym[i].getAttribute("title");
var acronym_temp = acronym[i].firstChild.nodeValue;
...
}
Création des balises dt et dt

C'est ici la partie la plus longue à écrire. Du fait que chaque élément dd et dt contient du texte, il faut à chaque fois créer le noeud dt ou dd, puis créer un noeud de type texte qui contient le texte. Ensuite, dans un second temps, on assemble les deux, l'élément et l'élément de type texte, avant de les ajouter à la liste de définitions. Le code sera certainement plus parlant qu'un long discours.

var dt = document.createElement("dt");
var dt_text = document.createTextNode(acronym_temp);
dt.appendChild(dt_text);

var dd = document.createElement("dd");
var dd_text = document.createTextNode(def_temp);
dd.appendChild(dd_text);

dl.appendChild(dt);
dl.appendChild(dd);
Finitions

Encore une partie assez verbeuse, puisqu'il nous reste à créer une balise d'entête, une balise div globale qui contiendra le tout et finalement ajouter le tout au document lui même. La balise d'entête se construit de la même manière que nous avons construit les balises dt ou dd. Petite particularité, la balise div doit contenir un attribut id initialisé sur la valeur menu. Ici encore, le code parlera plus simplement qu'un long discours.

var h = document.createElement("h2");
var h_text = document.createTextNode("Abbréviations");
h.appendChild(h_text);

var div = document.createElement("div")
div.setAttribute("id","menu")

div.appendChild(h);
div.appendChild(dl)

document.body.appendChild(div);

Relation script / document

De la même manière qu'il est intéressant et recommané d'externaliser les feuilles de style CSS, il en va de même pour le Javascript. Nous allons donc externaliser l'ensemble des fichiers Javascript utilisé dans une page. Par la même occasion, affrenchissons nous de la problématique du temps de chargement de la page.

En effet, le chargement de la page et de ses fichiers liés se fait de manière procédurale... c'est à dire au fur et à mesure.

Donc, si nous exécutons un code depuis un fichier de code Javascript chargé dans l'entête du fichier HTML, rien ne nous garantit que la page HTML elle même, sera intégralement chargée à ce moment là. Ouvrez à cette occasion les fichiers DOM_scripting_03.htm & DOM_scripting_03.js prévus à cet effet et qui vont pouvoir mettre en évidence cette problématique.

Le fichier Javascript contient une simple fonction qui affiche un message d'alerte indiquant l'argument transmis suivis du nombre d'éléments de type <p> contenus dans le document. Si vous testez ce document dans un navigateur, le premier message affiche depuis le script : 0 et le second depuis le body : 3.

En fait, lorsque le script, qui est lié, s'exécute, l'intégralité de la page n'est pas encore chargée, ce qui explique le 0 élément <p>. Alors que lorsque le script lancé depuis l'argument placé dans la balise body s'exécute, la page est déjà chargée, et les 3 éléments <p> sont bien interceptés, donc comptabilisés.

Nous allons aborder la partie évènementielle du DOM Scripting, n'hésitez pas à en parcourir les bases depuis le tutorial sur l'introduction au DOM.

Prise en compte de l'évènementiel

Bien qu'il existe une multitude de fonctions évènementielles, nous allons nous concentrer sur les deux principales, qui sont le chargement d'un objet, quelqu'il soit, page, document, image, etc... et l'interaction utilisateur au travers de la souris, avec un clic sur un lien de type <a> ou sur tout autre élément que le DOM ciblera.

Depuis les dernières générations de navigateurs, le w3c ne cesse de recommander l'utilisation du DOM de niveau 2 sur les évènements qui procure des spécificités sur l'utilisation assez géniale d'écouteurs. Mais il existe encore des divergences entre les mastotondes de l'édition de navigateur.

Gestion du load

Différentes manières d'utiliser l'évènementiel :

  • soit on affecte un évènementiel à un objet de la manière window.onload=actionAgerer() par exemple qui affecte un évènement de chargement à l'objet window,
  • soit on place un écouteur sur l'objet à la manière window.addEventListener("load",actionAgerer(),true).

Les deux manières fonctionnent et sont utilisables, mais comme d'habitude chacune vient avec son lot d'avantages et bien sûr son lot d'inconvénients. Plusieurs articles discutaillent le sujet, notamment :

Quoiqu'il en soit, la palisse dirait, il faut bien utiliser une méthode qui soit efficace dans notre situation et qui réponde à nos besoins. Pour la suite de ce tutorial, nous allons utiliser la méthode proposée par Peter-Paul Koch, qui consiste à ajouter autant de fonctions à traiter lors du chargement dans un gestionnaire master :

function addLoadEvent(func) {
var oldonload = window.onload;
if (typeof window.onload != 'function') {
window.onload = func;
} else {
window.onload = function() {
oldonload();
func();
}
}
}

Gestion du click

Ensuite, en ce qui concerne la gestion des interactions utilisateur basées sur des clics ou autre type d'entrées, il existe diverses manières de les apposer. La première, la plus simple, la plus directe et pas forcément la plus efficace, loin s'en faut, le pseudo protocole javascript. En effet dans l'attribut href d'un lien, il suffit de pointer sur un lien du style :

<a href="javascript:actionAgerer();">...</a>

Le hic est que beaucoup de navigateurs anciens ne gèrent pas ce protocole et du coup ne suivent pas l'interaction. De plus, si l'utilisateur à désactivé Javascript, il perd tout, action et interaction. Une manière un peu détournée est d'utiliser le gestionnaire d'évènement au sein de la balise <a> et de renseigner l'attribut href par un #, de la manière suivante :

<a href="#" onclic="actionAgerer();return false;">...</a>

Le return false en fin de fonction est utile pour éviter que l'attribut href soit intercepté. Bien que sa valeur ne soit pas une url qui redirigerait la page vers un autre emplacement, l'ancre # est reconnue par beaucoup de navigateurs qui interpréteraient cela comme un rechargement de la page sur le sommet.

Enfin, une dernière variante consiste à utiliser le DOM Scripting pour créer à la volée des actions combinées, utilisant soit l'attribut onclick en usant du raccourci objet.onclic = actionAgerer(), soit en plaçant un écouteur sur l'élément affecté par une interaction, de la manière suivante :

objet.addEventListener("clic",actionAgerer(),true)

Nous utiliserons alternativement objet.onclik = actionAgerer() ou objet.addEventListener("click",actionAgerer(),true). Libre à vous par la suite d'adapter le style et le code à vos besoins.

Gestion discrète du Javascript

Bien qu'il soit possible de placer directement le javascript au sein du fichier HTML, il est important de ne pas baser l'interaction de celui-ci au coeur du fonctionnement de la page web qu'il affecte. En effet, si l'utilisateur à choisi de désactiver Javascript sur son navigateur, aucune interaction n'étant possible, la page deviendra inutile en dehors de son propre contenu.

Pour cela il est bon de penser aux interactions du Javascript comme un complément de fonctionnalités, un confort ergonomique suplémentaire et un enrichissement de l'expérience utilisateur.

Il est donc préférable d'ajouter les évènements onclick avec Javascript, plutôt que de placer ces évènements dans le document HTML. Les pages possèderont donc leur propre fonctionnement sans Javascript, et s'enrichiront au chargement de celui-ci.

Pensez continuellement à tester le comportement de vos pages en désactivant Javascript. A ce sujet, Firefox offre parmi la pléiade d'outils de la web developer tool's bar, un menu très fonctionnel.

Mise en place d'une gallerie d'images

Présentation et objectifs

Afin de mettre en application une approche alternative à celle abordée dans la première partie de ce tutorial, nous allons améliorer l'interaction HTML d'une gallerie d'images lors du chargement de la page.

A l'origine, l'interaction utilisateur est basée sur des éléments de liste <li> qui contiennent une image <img> et un lien <a>. Les liens de type <a> pointent vers des images plus grandes, ce qui oblige d'une part, à recharger une nouvelle page et d'autre part, de naviguer en retour pour revenir à la page de départ.

Nous allons donc supprimer le lien et placer une interaction directement sur les images, qui auront en charge la permutation de l'image cible présente sur la page.

Nous ajouterons ensuite un menu déroulant, qui commute la présentation, c'est à dire, présente soit des icônes seules, soit des icônes accompagnées d'un texte.

Document, fichiers liés et initialisation

Commençons par télécharger les fichiers sources de base dom_scripting_04.htm, dom_script_04.css et explorons leur construction. Il existe deux parties principales, <div id="menu"> qui contient la liste d'images et les liens, et <div id="contenu"> qui présente le reste de la page dont le titre <h3 id="presentation"> et l'image <img id="apercu" /> en cours de présentation.

Nous allons utiliser dans un premier temps, un fichier Javascript de chargement, comme nous l'avons abordé dans l'exercice précédent, un simple fichier javascript qui contient la fonction. Appelez le par exemple, chargement.js et liez le dans l'entête <head> du document HTML. Puis créez un nouveau document Javascript,

function genereGallerieImage(){
...
}
addLoadEvent(genereGallerieImage);

Créez une fonction genereGallerieImage() et ajoutez là à l'évènement de chargement. Enregistrez et nommez le fichier javascript dom_scripting_04.js puis liez le également au document HTML. Prenez cependant soin, de le lier en second lieu par rapport à celui qui gère le chargement.

<script type="text/ecmascript" src="/chargement.js"></script>
<script type="text/ecmascript" src="/dom_scripting_04.js"></script>

Génération de la gallerie

Boucle pour générer la gallerie

La fonction prepareGallerie() en place, il nous faut commencer par cibler l'élément ayant l'identifiant #menu, nous pourrons ainsi facilement accéder à l'ensemble des éléments <li> qui le constitue. Suite à cela, nous pourrons au travers d'une boucle affecter chacun de ces éléments en adaptant leur présentation et leur ajoutant une interaction utilisateur.

var menu_actuel = document.getElementById('menu');
var gallerie = menu_actuel.getElementsByTagName('li');
var nb_liens = gallerie.length
for (var i=0; i<nb_liens;i++){
...
}

Une fois dans la boucle qui parse chaque élément de la liste, nous devons remplacer l'action du lien <a> par un clic sur l'image. L'idée étant que cette action permute l'image d'aperçu, par l'image contenu dans le lien. Rappelons nous, ci-dessous, de l'aspect d'un de ces éléments de liste et voici ce que nous allons faire pour ce tutorial :

<li><img src="/pommes_s.png" alt="Pommes Grani Smith" /><a href="/pommes_b.png">Pommes</a></li>

Il existe plusieurs approches et manières de procéder, toutes ont leur intérêt. Nous allons en explorer une en particulier... Décortiquons une à une chaque étape à mettre en place :

  • Isoler l'image dans une variable
  • Affecter une propriété lien à cette image
  • Initialiser cette variable à la valeur du lien <a>
  • Placer une action onclik sur l'image qui interpellera la fonction permutteImage()
  • Supprimer la balise <a> du document
Récupération des informations

On repère la balise <img> depuis l'élément de liste et on la stocke dans une variable temporaire link_temp. Il faut noter que la fonction getElementsByTagName() renvoie un tableau, et du fait que nous savons pertinemment que dans notre document il n'y a qu'une seule image par élément de liste, nous pouvons directement récupérer en dur la première image de ce tableau.... d'où le [0]

Affectons une propriété lien à cet objet et initialisons la, à la valeur de l'attribut href du lien actuel. De ce fait, nous conservons le lien vers la grande image au sein de l'objet image temporaire.

var link_temp = gallerie[i].getElementsByTagName('img')[0]
link_temp.lien = gallerie[i].getElementsByTagName('a')[0].href
Mise en place de l'action

En ayant mis en place un pointeur, il est alors facile de directement placer un évènement onclick() sur l'image. Il suffit d'interpeler alors la fonction permutteImage() et de passer la référence de l'objet lui même. Le mot clé this est tout indiqué pour cela.

link_temp.onclick = function(){
permutteImage(this)
}
Supression du lien par défaut

Tout est en place au niveau de l'initialisation de la gallerie, il ne nous reste plus qu'à retirer la balise <a> du document. Par contre, dans l'éventualité d'une récupération ultérieure, il peut être intéressant d'en stocker le contenu dans une propriété.

Quel en serait alors le meilleur emplacement ? Rappelez vous, nous avions créer une variable gallerie qui contient l'ensemble des éléments de liste. Pourquoi ne pas créer une variable a que nous placerions à l'index adéquat, de la manière suivante :

gallerie[i].a = gallerie[i].removeChild(gallerie[i].getElementsByTagName('a')[0])

Fonction de permutation d'image

Mise en place de la fonction

Le remaniement du document et les appels de la fonction sont maintenant en place, il nous reste juste à définir et à mettre en place la fonction d'accueil. Cette fonction reçoit un argument, identifions le comme arg.

function permutteImage(arg){
...
}
Récupération des informations

La fonction devant permutter la grande image d'apercu et le texte de titre de présentation, commençons par utiliser deux variables texte_temp et img_temp qui vont se charger d'identifier et pointer respectivempent les balises <h3 id="presentation"> et <img id="apercu">

var texte_temp = document.getElementById('presentation')
var img_temp = document.getElementById('apercu')
Affichage des nouvelles informations

Affectons ensuite ces deux variables de leur nouveau contenu qui varie en fonction de l'argument arg reçu. Notez, que nous aurions pu ne pas faire appel à des variables tampons. Le code aurait juste était un peu plus obscur.

texte_temp.firstChild.nodeValue = arg.alt
img_temp.src = arg.lien

Menu déroulant et interaction

Ajout de l'action sur le menu et mise en place de la fonction

Nous allons ajouter une fonctionnalité que l'on retrouve dans grand nombre d'applications, à savoir, la possibilité de présenter les boutons en tant qu'icônes seuls ou icônes et textes. Pour cela nous allons utiliser un menu déroulant qui proposera le choix, et une fonction qui va prendre en charge le filtre et l'action appropriée.

Commençons par définir la fonction, appelons permutteIcone(arg), pensons à définir l'utilisation d'un argument qui aura pour fonction de préciser le choix utilisateur.

function permutteIcone(arg){
...
}

Du côté du sélecteur en menu déroulant, il faut commencer par définir les options, Images & Images et Textes qui renveront respectivement les valeurs I & IT. Puis, ajoutons un évènement onchange() sur le menu déroulant.

Cet évènement se déclanche à chaque modification de l'état de l'objet auquel il est affecté. Enfin, ajoutons un paramètre qui reflète la valeur de la sélection de l'utilisateur. Une simple utilisation d'un DOM de niveau 0 suffit, profitons en.

<select name="mode" id="mode" onchange="permutteIcone(this.options[this.selectedIndex].value);">
Récupération des informations

Côté fonction, nous allons devoir procéder en trois étapes, voici les principales phases de cette opération :

  • la première consiste à récupérer les éléments à affecter et à les placer dans une liste.
  • ensuite nous devrons filtrer le type d'action à porter
  • et enfin affecter les objets concernés en fonction

Comme précédemment, nous ciblons l'ensemble des éléments de liste identifiés par l'id #menu, ensuite extrayons-en tous les éléments de type <li>. Nous pourrions alors soit utiliser une boucle for (var i in objet) soit une classique for (var i=0; nombre d'éléments, i++). Optons pour la seconde, donc comptons combien notre tableau contient d'éléments.

var menu_actuel = document.getElementById('menu');
var gallerie = menu_actuel.getElementsByTagName('li');
var nb_liens = gallerie.length
Boucle et tests de conditions

Installons la boucle, et plaçons à l'intérieur, une base de filtre. Là encore, nous avons plusieurs possibilités, soit une classique série de tests, if () else, soit une plus claire et lisible structure switch () case. Utilisons comme élément à comparer l'argument reçu par la fonction.

for (var i = 0;i<nb_liens;i++){
switch (arg){
...
}
}
Cas Image seule, supression des informations

Dans le cas où le paramètre envoyé est I, il nous suffit de retirer l'élément <p>. Si nous souhaitons un code plus propre et adaptable, il nous faudrait au préalable filtrer la présence d'un tel élément avant de le retirer.

case "I":
gallerie[i].removeChild(gallerie[i].getElementsByTagName('p')[0])
break;
Cas Image et texte, récupération des informations

Le cas où l'on souhaite les Images et le texte, le code va être plus fourni, il va nous falloir :

  • Créer un élément de type <p>
  • Récupérer la valeur du texte de l'ancienne balise <a> que nous avions retirée lors de l'initialisation et stockée temporairement dans une propriété a.
  • Créer un élément de type texte
  • Placer l'élément de texte dans la balise <p>
  • et enfin ajouter la balise <p> à la gallerie
case "IT":
var p = document.createElement('p')
var recup_a = gallerie[i].a.firstChild.nodeValue
var p_texte = document.createTextNode(recup_a)
p.appendChild(p_texte)
gallerie[i].appendChild(p)
break;
 


Puce et Média > AJAX > Le DOM Scripting