Retour

Récupérez l'archive contenant les fichiers nécessaires aux exercices suivants et décompressez la dans votre espace de travail.

Cliquez sur le titre d'un exercice pour le découvrir.

Les fichiers créés au cours des différents exercices sont souvent réutilisés pour d'autres exercices ultérieurs. Veillez donc à toujours en avoir une version disponible.


On va agir dans ces exercices sur la structure de l'arbre DOM et, sur les événements, utiliser this et gérer des abonnements et désabonnements dynamiques.

Modifier l'arbre DOM

Création, insertion, suppression d'éléments. Abonnement, désabonnement
On rappelle que dans une fonction d'écoute (listener function) this désigne toujours l'élément sur lequel l'événement a été déclenché.
Relisez puis gardez à porter de main le document de cours qui aborde les différentes méthodes de manipulation de la structure : createElement, appendChild, insertNode, etc.
Récupérez le fichier transformation-dom.html et sa feuille de style.
  1. Créez et complétez le fichier transformation.js pour qu'un clic sur le bouton #ajouter ait pour effet
    1. de demander à l'utilisateur de proposer l'url d'une image (via window.prompt),
    2. d'utiliser createElement pour créer un élément <img> dont la source est cette url,
    3. d'attribuer la classe image à cet élément créé,
    4. d'utiliser appendChild pour ajouter cet élément créé à la fin du contenu de l'élément #images.
  2. Testez (en utilisant par exemple les images fournies dans le dossier images).
  3. Modifiez la fonction qui permet l'ajout d'une image pour qu'un clic sur l'image ajoutée ait pour effet
    1. de créer une copie de cet élément image à l'aide de la fonction cloneNode (voir sur le MDN).

      Pour la distinguer de l'original vous ajouterez à cette copie une couleur d'arrière-plan, rgba(0,128,0,0.3) par exemple.

    2. d' insérer cette copie créée dans l'élément #images juste avant l'élément correspondant à son original. Vous utiliserez la fonction insertBefore ainsi que la propriété parentNode (voir sur le MDN).
  4. Testez.
  5. Pour éviter les copies multiples, faites en sorte que sur chaque image originale seul le premier clic ait un effet, pas les suivants.
  6. Ajoutez un gestionnaire d'événement de telle sorte que lors d'un clic sur une copie, l'élément correspond soit purement et simplement supprimé (de l'arbre DOM). Vous utiliserez la fonction removeChild.
  7. On va modifier maintenant l'action d'un clic sur les images ajoutées mis en place à la question 3.
    Avant de poursuivre, pour en garder une trace, faites une copie du travail précédent ou utilisez des noms de fonction d'écoute différents.
    On souhaite cette fois qu'un clic sur une des images ajoutées crée à nouveau une copie de cette image mais que cette copie vienne se placer dans l'élément #stock.

    De plus un clic sur le bouton #raz aura pour effet de supprimer toutes les images de #images sans toucher à celle de #stock.

  8. Testez.
  9. Faites les modifications nécessaires pour que chaque image ajoutée reçoive un id de la forme I-imageI est le numéro d'ajout de l'image (obtenu via un compteur du nombre d'ajouts que vous pouvez gérer à l'aide d'une variable globale).
  10. A l'aide de la fonction parseInt faites en sorte que lors de la création d'une copie de l'image d'id N-image, sa copie reçoive un id de la forme N-copie (avec le même N évidemment !).
  11. Complétez ce qui précède pour qu'une fois qu'une image a été copiée, le fait de la survoler à la souris (dans la zone #images) a pour effet de mettre en rouge la background-color de sa copie. La fin de survol supprime cette coloration.
Table des matières
Nous allons voir comment générer et insérer automatiquement une table des matières (sans lien interne) dans un document. La table des matières que l'on veut insérer aura une structure HTML de la forme :
                    <div id="toc">
                        <div class="h1">Tim Berners-Lee</div>
                            <div class="h2">Biographie</div>
                            <div class="h2">L'invention du World Wide Web</div>
                                <div class="h3">Premiers pas</div>
                            <div class="h2">Le W3C</div>
                                <div class="h3">Création</div>
                                <div class="h3">Des standards</div>
                            <div class="h2">Quelques titres et récompenses</div>
                        <div class="h1"> La côte d'Ajoncs</div>
                            <div class="h2"> Présentation</div>
                            <div class="h2">Le Sentier des Douaniers (ou GR®34)</div>
                    </div>
                    
pour produire un résultat qui ressemblera à :
Exemple de table des matières générée.
Exemple de table des matières générée.
  1. Récupérez le fichier table-matiere.html et sa feuille de style. Visualisez-le et vérifiez rapidement la présence de balises <h1>, <h2> et <h3>. Faites le lien entre ces éléments et le code HTML ci-dessus pour comprendre le code qu'il va falloir produire.
  2. Réalisez une fonction creeTableMat qui crée et a pour résultat un nouvel élément de type <div> et d'id toc. Le contenu de cet élément sera conforme à la structure proposée ci-dessus. Il faut donc reprendre les éléments <h1>, <h2> et <h3> dans l'ordre du document, puis créer pour chacun d'entre eux un nouvel élément <div> avec la bonne classe et le bon contenu texte. Ces éléments sont ajoutés les uns après les autres comme fils de l'élément div#toc créé.
    Que fournit comme résultat l'expression document.querySelectorAll("h1,h2,h3") ?
    La propriété nodeName fournit pour un élément le nom de sa balise en majuscules.
    Vous pouvez réutiliser la fonction formatElement d'un précédent exercice pour créer le texte de chacun des éléments <div>.
  3. Réalisez une fonction insertTableMat qui insère l'élément créé par la fonction précédente en tout début de document, avant l'actuel premier noeud fils de <body>. Voir la propriété firstChild (cf. sur MDN). Cette fonction ajoutera également une marge gauche de 200px à l'élément <body>.
  4. Testez.
  5. Quelle solution proposez-vous pour que la génération et l'insertion de cette table des matières se fasse automatiquement au chargement du document ?
    Nous avons déjà rencontré une situation où nous voulons réalisez une opération automatiquement au chargement du document, laquelle ?
Table des matières (v2)
On reprend le travail précédent, on va ajouter des numéros et des liens aux titres créés dans la table des matières vers les élément de titre correspondant. Il suffit pour cela d'insérer des ancres dans le document HTML et d'envelopper les élements div.tocX dans des hyperliens qui ciblent ces ancres.
  1. Définissez trois compteurs, un par niveau de titre, et réalisez une fonction creeNumerotation qui prend en paramètre un élément (par hypothèse de type <h1>, <h2> ou <h3>) et a pour résultat une chaîne de caractères, construite à partir de ces compteurs, qui représente le numéro de ce titre dans la table, comme dans la figure ci-dessous :
    Exemple de table des matières avec numéros.
    Exemple de table des matières avec numéros.
    Modifiez ensuite creeTexteTableMat pour ajouter ces numéros devant les textes des titres.
    Il est nécessaire de remettre à 0 les compteurs des niveaux 2 et 3 au bon moment.
    Vous pouvez aussi ajouter les numéros dans le document, pour chacun des éléments de titre parcouru.
  2. Modifiez (après en avoir fait une sauvegarde) la fonction creeTexteTableMat précédente de manière à, pour chaque élément e de titre examiné 
    • insérer dans le document avant e un élément <span> dont l'id est le numéro attribué au titre dans la table des matières.
    • placer le texte <div> créé pour e dans le texte d'un élément <a> dont la cible est ce même id. Ainsi le code initial (toute première version) :
                         
                          <div class="h1">La côte d'Ajoncs</div>                   
                          
      devient
                         
                             <a href="#2."><div class="h1">2. La côte d'Ajoncs</div></a>
                          
      Et dans le document
                         
                          <h1 id=​"premier">​La côte d'Ajoncs​</h1>
      devient
                          <span id=​"2.">​</span>​  <h1 id=​"premier">​La côte d'Ajoncs​</h1>