Aller au menu - Aller au contenu

Icône XHTML, Javascript et DOM

Mise à jour : 05/03/2009
454 visites depuis 7 jours , dont 98 sur ce chapitre , classé 235/777
Pfiouh... Nous y voilà enfin. Il était temps. Nous allons pouvoir utiliser toutes nos connaissances, et faire enfin des pages dynamiques.

Je vais vous donner ici pas mal d'exemples, avec les codes cachés, pour que vous essayiez d'appliquer ce que je vous ai appris (enfin j'espère).

Enfin, je vous donnerai quelques pistes d'applications intéressantes au DHTML, javascript et DOM.

Alors, on est partis ? :p
Sommaire du chapitre :
Icône du chapitre
Chapitre précédent Sommaire

Utilisation combinée

Avant toute chose, il nous faut connaître une dernière méthode pour pouvoir utiliser pleinement le DHTML. C'est la méthode removeChild, qui va nous permettre de nettoyer les documents XHTML avant ou après les avoir modifiés.

Elles s'utilise de la manière suivante :

Code : JavaScript
1
2
3
var node = document.getElementById("node_à_supprimer");
var parent = node.parentNode;
parent.removeChild(node);


En utilisant cette méthode, vous supprimez également tous les noeuds enfant de node.


Voilà : c'était pas bien compliqué et on est maintenant fin prêts.

Pour le premier exemple, je vais vous faire la démonstration. Nous allons nous équiper d'un document .html, d'un document .js et d'un document .css (pour faire joli ;) ). Ainsi que de deux images que vous pouvez récupérer ici et ici.

Le but ici est d'afficher un texte quand rien de spécial ne survient ; le drapeau français quand la souris est au-dessus du lien français, et le drapeau anglais quand la souris est au-dessus du lien english.

Si vous voulez tester.

Code : HTML
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr">

        <head>
                <title>Page de test</title>

                <script type="text/javascript" src="test.js"></script>
                <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
                <meta name="author" lang="fr" content="Bastien Moyet" />
                <link rel="stylesheet" media="screen" type="text/css" title="Classic" href="style.css" />

        </head>


        <body>
                <p id="testbox">If you see an image appearing in the current box when your mouse is over the link below javascript is enabled on your computer</p>
                <p class="javascript"><a href="test.html" onmouseover="javascript:flag(1)" onmouseout="javascript:flag(0)">Engish</a> <a href="test.html" onmouseover="javascript:flag(2)" onmouseout="javascript:flag(0)">Français</a></p>
                
        </body>

</html>


Code : JavaScript
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
function flag(type){
        if( type == 1 ){//si la variable reçue vaut 1
                //Suppression de l'ancien contenu
                var paragraphe = document.getElementById("testbox");
                var old_contenu = paragraphe.firstChild;                
                paragraphe.removeChild(old_contenu);
                //Ajout du nouveau contenu
                var img = document.createElement("img");
                img.setAttribute("src","english.jpg");
                img.setAttribute("alt","english flag");
                paragraphe.appendChild(img);
                
        }
        else if( type == 2 ){//si la variable reçue vaut 2 
                //Suppression de l'ancien contenu              
                var paragraphe = document.getElementById("testbox");
                var old_contenu = paragraphe.firstChild;                
                paragraphe.removeChild(old_contenu);
                //Ajout du nouveau contenu
                var img = document.createElement("img");
                img.setAttribute("src","french.gif");
                img.setAttribute("alt","french flag");
                paragraphe.appendChild(img);
        }
        else{//si la variable reçue vaut 0
                //Suppression de l'ancien contenu
                var paragraphe = document.getElementById("testbox");
                var old_contenu = paragraphe.firstChild;
                paragraphe.removeChild(old_contenu);
                //Ajout du nouveau contenu
                var texte = document.createTextNode("If you see an image appearing in the current box when your mouse is over the link below javascript is enabled on your computer");
                paragraphe.appendChild(texte);
        }
}


Code : CSS
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
body
{
        background-color: #8fc3cb;
        padding-left: 30%;
}

fieldset
{
        border: none;
}

#testbox
{
        border: thin dotted black;
        position: absolute;
        top: 10%;
        left: 30%;
        width: 300px;
        height: 202px;
}

.javascript
{
        position: absolute;
        top: 50%;
        left: 30%;
        width: 300px;
        text-align: center;
}


Voilà pour un premier petit exemple.

Exercice 1 : Afficher des informations pour un formulaire

Maintenant, faisons un formulaire qui affiche une description du champ sur lequel on clique dans un paragraphe sur notre page, quand l'utilisateur clique dans le champ. A vous de jouer. La réponse est ici, juste pour ceux qui ne trouvent pas le moyen de vérifier.

Pour donner un point de départ à ceux qui sèchent, voilà un petit énoncé.
On a 3 champs:
- nom
- prénom(s)
- date de naissance
Quand je clique sur le champ nom, j'ai un message qui s'affiche dans un <p> qui me dit de rentrer mon nom, et éventuellement mon nom de jeune fille si je suis une femme mariée.
La même chose quand je clique sur le champ prénom(s), avec les différents prénoms.
Et enfin quand je clique sur le champ date de naissance, il m'indique le format à utiliser.

A vos Bloc-note. ;)

Voici pour ceux qui veulent voir un exemple.

Secret (cliquez pour afficher)

Code : HTML
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<p id="testbox">If you see information appearing in the current box when you click in a text field javascript is enabled on your computer</p>
                <div class="javascript">
                        <form action="test.html" method="post">
                                <fieldset>
                                        <label>Nom <input type="text" name="nom" onFocus="javascript:infos(1)" onBlur="javascript:infos(4)" /></label><br />
                                        <label>Prénom <input type="text" name="nom" onFocus="javascript:infos(2)" onBlur="javascript:infos(4)" /></label><br />
                                        <label>Date de naissance<input type="text" name="nom" onFocus="javascript:infos(3)" onBlur="javascript:infos(4)" /></label>
                                        <input type="submit" value="Valider" />
                                </fieldset>
                        </form>
                </div>

Code : JavaScript
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
function infos(number){
        if(number == 1){
                //Suppression de l'ancien contenu
                var paragraphe = document.getElementById("testbox");
                var old_contenu = paragraphe.firstChild;
                paragraphe.removeChild(old_contenu);
                //Ajout de l'information
                var info = document.createTextNode("Entrez votre nom de famille. Si vous êtes une femme mariée, entrez également votre nom de jeune fille");
                paragraphe.appendChild(info);      
        }
        else if(number == 2){
                //Suppression de l'ancien contenu
                var paragraphe = document.getElementById("testbox");
                var old_contenu = paragraphe.firstChild;
                paragraphe.removeChild(old_contenu);
                //Ajout de l'information
                var info = document.createTextNode("Entrez votre Prénom. Si vous avez plusieurs prénoms, veuillez les entrer tous ");
                paragraphe.appendChild(info);
        }
        else if(number == 3){
                //Suppression de l'ancien contenu
                var paragraphe = document.getElementById("testbox");
                var old_contenu = paragraphe.firstChild;
                paragraphe.removeChild(old_contenu);
                //Ajout de l'information
                var info = document.createTextNode("Entrez votre date de naissance sous la forme dd/mm/yyyy");
                paragraphe.appendChild(info);
        }
        else if(number == 4){
                //Suppression de l'ancien contenu
                var paragraphe = document.getElementById("testbox");
                var old_contenu = paragraphe.firstChild;
                paragraphe.removeChild(old_contenu);
                //Ajout de l'information
                var info = document.createTextNode("If you see information appearing in the current box when you click in a text field javascript is enabled on your computer");
                paragraphe.appendChild(info);
        }
}



Si vous avez réussi seul ce petit exercice, le reste ne devrait plus vous poser de problème.

Exercice 2 : Un formulaire dynamique

Voilà quand même un dernier exercice plus dur, qui demande un peu plus de temps. Nous allons utiliser ici l'insertion d'événements dynamiques. Si vous arrivez à le faire, il ne vous manquera plus qu'un peu de pratique pour faire des sites dynamiques et pratiques.

Dernier exercice : Créer un formulaire avec des champs text qui s'ajoutent et se suppriment à volonté (attention : il faut bien supprimer le bon formulaire), ainsi qu'une liste déroulante qui proposera un choix parmi n valeurs (n étant le nombre de champs text), ces valeurs étant le contenu des champs de texte.

Voici pour ceux qui veulent un exemple.

Voilà une liste de quelques indices, et ce dont vous aurez besoin (je ne vous en ai pas parlé) :
Code : JavaScript
1
2
var balise = document.getElementById("option");
var value = balise.getAttribute("attribut");//récupère la valeur d'un attribut


Quand vous avez un node pointant sur un input, vous pouvez récupérer la valeur se trouvant dans le champ dynamiquement (en effet : on ne peut pas utiliser getAttribute("value"). :(

Code : JavaScript
1
2
var input = document.getElementById("option");
var contenu_champ = input.value;


Pour récupérer ce que vaut un node text, il vous faut procéder ainsi :

Code : JavaScript
1
2
3
4
var texte = document.getElementById("my_paragraphe").firstChild;
var contenu = texte.nodeValue;
//On peut également modifier la valeur d'un textNode ainsi :
var  text.nodeValue = "Nouveau texte";


Et enfin, une fonction qui peut vous être utile :

Code : JavaScript
1
2
var texte = "Balise 2"
var numero = texte.split(" "); //numero devient alors un tableau qui contient les bouts de phrases de texte séparés par des " "


On aura donc numero[0] qui vaut "Balise" et numero[1] qui vaut "2".

Secret (cliquez pour afficher)

Code : HTML
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
<p id="testbox">If you see information appearing in the current box when you click in a text field javascript is enabled on your computer</p>
                <div class="javascript">
                        <form action="test.html" method="post">
                                <fieldset id="zone_text">
                                        <p class="lien" onClick="javascript:add()">Ajouter un champ texte</p><br />
                                </fieldset>
                                <fieldset id="liste_deroulante">
                                        <select name="liste">
                                        </select>
                                        <input type="submit" value="Valider" /><br /><br />
                                </fieldset>
                        </form>
                </div>
                <script type="text/javascript">
                        add();
                </script>

Code : JavaScript
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
function refresh(event){
        //On sélectionne le premier et le deuxième fieldset
        var liste = document.getElementById("liste_deroulante");
        var text_fieldset = document.getElementById("zone_text");
        
        //On récupère la position de notre champ texte
        var node_source = (document.all)?event.srcElement:event.target;
        var position = node_source.previousSibling.nodeValue.split(" ")[1];
        
        //On récupère la valeur dans la champ texte
        var labels = text_fieldset.getElementsByTagName("label");
        var label = labels[position-1];
        var input = label.getElementsByTagName("input")[0];
        
        //On met à jour la liste déroulante
        var option = liste.getElementsByTagName("option")[position-1];
        option.firstChild.nodeValue = input.value;
}

function del(event){
        //on sélectionne le premier fieldset et on récupère tous les label qu'il y a à l'intérieur
        var text_fieldset = document.getElementById("zone_text"); 
        var labels = text_fieldset.getElementsByTagName("label");
        
        //On récupère le noeud qui émet l'évènement et sa position grâce au texte Valeur x
        var node_source = (document.all)?event.srcElement:event.target;
        var position = node_source.previousSibling.firstChild.nodeValue.split(" ")[1];
        
        //On décale d'un cran inférieur tous les éléments situés après l'élément à supprimer
        for(var i=position;i<labels.length;i++){
                var label = labels[i];
                var input = label.getElementsByTagName("input")[0];
                
                input.setAttribute("name","nom"+i);
                
                label.firstChild.nodeValue = "Valeur "+i+" ";
        }
        
        //Suppression de la zone de texte, du lien et du saut de ligne
        var label = labels[position-1];
        var lien = label.nextSibling;
        var br = lien.nextSibling;
        text_fieldset.removeChild(label);
        text_fieldset.removeChild(lien);
        text_fieldset.removeChild(br);
        
        //Suppression de l'élément d'option
        var liste = document.getElementById("liste_deroulante");
        var select = liste.getElementsByTagName("select")[0];
        var option = select.getElementsByTagName("option")[position-1];
        select.removeChild(option);
        
}

function add(){
        //On compte le nombre de label et on sélectionne le premier fieldset
        var count = document.getElementsByTagName("label").length;
        var text_fieldset = document.getElementById("zone_text");
        count ++;
        
        //création du label( <label>Valeur x <input type="text" name="nomx" value="" /></label>)  
        var input = document.createElement("input");
        input.setAttribute("type","text");
        input.setAttribute("name","nom"+count);
        input.setAttribute("value","");
        
        if(document.all) input.attachEvent("onkeyup",refresh);
        else input.addEventListener("keyup",refresh,true);
        
        var nom_label = document.createTextNode("Valeur "+count+" ");
        var label = document.createElement("label");
        label.appendChild(nom_label);
        label.appendChild(input);
        
        //Création des élement br et p ( <p class="lien">Supprimer</p><br /> )
        var br = document.createElement("br");
        var del_text = document.createTextNode("Supprimer");
        var lien_del = document.createElement("p");
        lien_del.setAttribute("class","lien");
        lien_del.setAttribute("className","lien");

        if(document.all) lien_del.attachEvent("onmouseup",del);
        else lien_del.addEventListener("mouseup",del,true);
        
        lien_del.appendChild(del_text);

        //On raccroche ici tous nos éléments virtuels à une balise de notre fichier XHTML. Ils sont alors affichés   
        text_fieldset.appendChild(label);
        text_fieldset.appendChild(lien_del);
        text_fieldset.appendChild(br);
        
        //Ajout d'un élément d'option vide dans notre liste ( <option value=""></option> )
        var liste = document.getElementById("liste_deroulante");
        var select = liste.getElementsByTagName("select")[0];
        var option = document.createElement("option");
        var texte = document.createTextNode("");
        option.setAttribute("value","nom"+count);
        option.appendChild(texte);
        select.appendChild(option);
}

Ouverture et bibliographie

Avec tout ce que l'on a vu, j'imagine que vous avez déjà quelques idées sur les moyens d'utiliser le DHTML. Vous avez déjà pu voir avec les exemples que les formulaires peuvent devenir vraiment dynamiques et vraiment pratiques d'utilisation.

Entre autres, afin de créer des formulaires pour gérer votre site, par exemple. Je peux vous assurer que ça aide énormément.

Mais bien heureusement, le DHTML ne se limite pas qu'aux formulaires. Il y a d'ailleurs une chose dont je ne vous ai pas parlé du tout dans ce tuto, c'est la possibilité de modifier des attributs css.

Comment est ce qu'on peut faire ça ? Avec un setAttribute("style"... ?

Eh bien encore une fois, non. Il existe là aussi une méthode pour gérer ça, appelé... style. Pour l'utiliser, rien de plus simple : vous prenez une variable de type node et vous faites node.style.nom_du_style = "valeur_du_style".

Les pages fixes n'auront plus jamais la même saveur avec ça.

Et enfin, je vous ferai remarquer que le DHTML associé à du XMLHttprequest (comprendre AJAX) permet de non seulement rendre vos pages dynamiques du côté client, mais en plus d'aller chercher des informations sur votre serveur, sans que la page du client ait à se recharger.

Voilà : il ne me reste plus qu'à vous donner quelques bons liens pour appronfondir le cours, ou quelques bonnes références pour trouver une méthode (ou autre).

Je souhaite remercier ici les auteurs de ces sites qui m'ont été particulièrement utiles pour apprendre le DHTML. Je me suis évidement parfois inspiré de certains de ces sites, mais tout ce que je vous ai raconté vient de ce que j'ai compris.

Ressources utiles :
Objet Event : http://www.laltruiste.com/document.php [...] pt/event.html
Javascript et DOM : http://fr.selfhtml.org/javascript/
Style et DOM : http://fr.selfhtml.org/javascript/objets/style.htm

Pour approfondir le DOM et le XHTML :
http://nyams.planbweb.com/tutorial/

Comprendre le addEventListener :
https://developer.mozilla.org/fr/DOM/e [...] EventListener

Introduction à AJAX :
http://www.toutjavascript.com/savoir/xmlhttprequest.php3
Chapitre précédent Sommaire

Partager

25 commentaires pour "XHTML, Javascript et DOM"
Note moyenne : 3.26 / 4 (46 votes)
Pseudo Commentaire
Hors ligne hornetbzz # Posté le 09/02/2010 à 05:04:09
que la force soit avec toi
Avatar

Études : ESTACA

Ouah, c'est vraiment bien écrit: dense et précis.

Génial aussi bien quand on débute et que quand on a déjà fait ses premiers pas mais qu'on cherche un résumé.

Juste peut-être une pt'ite erreur ici sio on veut chipoter :
Citation
var texte = document.getElementById("my_paragraphe").firstChild;
var contenu = texte.nodeValue;
//On peut également modifier la valeur d'un textNode ainsi :
var texte.nodeValue = "Nouveau texte";
Hors ligne marcel35 # Posté le 12/04/2010 à 16:18:30

J'ai été surpris en voyant la correction du second exercice, ça ne ressemble pas du tout à ce que j'ai fait bien que le résultat soit identique ! :p

Code : JavaScript
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
function infos(champ)
	{

		var paragraphe = document.getElementById('testbox');
		var old_child = paragraphe.firstChild;
		
		var infos = new Array();
		infos['nom'] = 'Entrez votre nom de famille';
		infos['prenom'] = 'Entrez votre prénom';
		infos['dateN'] = 'Entrez votre date de naissance au format 0000-00-00';
		
		// Si aucun champ n'a le focus ont affiche le texte par défaut
		if (!champ)
			{
				var texte = document.createTextNode('Entrez vos informations');
				paragraphe.replaceChild(texte, old_child);
			}
		// Sinon on affiche l'info qui concerne le champ
		else
			{
				
				var texte = document.createTextNode(infos[champ.name]);
				paragraphe.replaceChild(texte, old_child);
			}
	}

Code : HTML
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<p id="testbox">Entrez vos informations</p>
	<div class="javascript">
		<form action="test1.html" method="post">
			<fieldset>
				<label>Nom <input type="text" name="nom" onFocus="javascript:infos(this)" onBlur="javascript:infos(0)" /></label><br />
				<label>Prénom <input type="text" name="prenom" onFocus="javascript:infos(this)" onBlur="javascript:infos(0)" /></label><br />
				<label>Date de naissance <input type="text" name="dateN" onFocus="javascript:infos(this)" onBlur="javascript:infos(0)" /></label><br />
				<input type="submit" value="envoyer" />
			</fieldset>
		</form>
	</div>


Ma façon de faire est-elle bonne ? Sinon pourquoi ?


edit : je vois dans les commentaires que tout le monde à une façon de faire différente. :-° C'est super flexible le JS dit donc !
Hors ligne Georges_ # Posté le 27/08/2010 à 08:31:19
Avatar

Ville : Sevres
Pays : France métropolitaine
Études : Sciences-Po

En tant que zéro, je suis largué.
Tu avances trop vite, le second exercice est déjà bien complexe pour un zéro et certaines notions ne sont pas expliquées dans le cours:
(document.all)?event.srcElement:event.target
Je vais faire un tour du côté de w3schools voir si je pige mieux.
Hors ligne mdr1 # Posté le 24/11/2010 à 18:04:24
你好吗?我很好!
Avatar

Très bon tutoriel ! Juste une petite faute :

Citation : Le tutoriel dans l'introduction
Alors, on est partis ? :p

Comme le "on" est la 3e personne du singulier, on devrait dire "Alors, on est parti ?"
 
Hors ligne slifer # Posté le 28/11/2010 à 13:11:59

Études : Faculté des Sciences Ain Chock Casblanca

Bonjour, je tiens à remercier SdZ pour ses nombreux tuto, pour moi c'est devenu mon cours principale (plus simple que celui du prof ^^), bref voila mon problème :
je fais un programme qui insère des lignes de formulaire en cliquant sur un boutton(Nouveau), la

ligne contien :
zone de texte associé à un calendrier pour saisir les date:
deux liste déroulante
une zone de texte qui change de "value" quand les listes déroulantes changent.

l'insertion se passe à merveille, mais puisque j'ai utilisé innerHTML, il y a une différence entre IE et FF, sur IE ça marche quand j'insère une ligne je la remplie et je clique sur mon Bouton pour insérer une deuxième ligne, j'ai la nouvelle et c'est reparti pour la remplir, je peux à tout moment revenir sur les lignes déjà insérée et les modifier, le malheur :waw: c'est avec FireFox, la première ligne s'insère normalement, je la rempli, mais une fois je clique sur le bouton d'insertion pour insérer une nouvelle ligne, il est bien insérée mais toutes les ligne précédente sont réinitialisée, ça veut dire que tout ce que j'ai saisi disparait (les liste déroulante reviennent sur l'option selected parDefaut, les zone de texte sont vide) et le calendrier n'apparait plus quand je clique sur la zone de texte de la date (onfocus engendre l'apparition du calendrier), bref sur FF ça ne marche que sur la dernière ligne insère, les précédentes sont toutes réinitialisées.
Après lecture du tuto j'ai essayé de faire l'insertion par DOM, par contre je rencontre un gros problème :colere: , la majorité de mes fonctions qui sont associées à des évènement des objets insèré contient des paramètred alors que dans ce tuto j'ai que addEventListner(Event,fonction,true) ou addAttachment(onEvent,fonction) SANS PARAMÈTRE, après tout ce long discours ma question est :
Comment associer des fonction qui contient des paramètre à des évènement inséré? :-°

P.S : si besoin du code je peux le copier mais je vous préviens il est troop long (surtout le calendrier)

Voir tous les commentaires