Grégory Bourguin
SysReIC - LISIC - ULCO
Web2 : TP01 (2 séances)

Préliminaires

Avant de commencer ce TP

Il est nécessaire que vous ayez compris le cours jusqu'à la partie Attributs spéciaux.

Pour commencer ce TP, je vous invite donc à (re)faire par vous-mêmes (et pas avec de bêtes des copier/coller) tous les exemples du cours concernés.

Ce TP suppose aussi que vous maîtrisez le positionnement d'éléments en CSS avec Flex.


Structure de Page Web

Template

Notre but va être de créer une page Web qui occupe toute la page avec :

  • Une entête principale (header)
  • Un conteneur (div qui occupe tout l'espace disponible). Ce conteneur accueillera des sections qui seront elles-mêmes composées d'articles.
  • Un pied de page (footer)

Le thème page sera le jeu bien connu Dark Souls (avec une préférence pour le III ).

Le template HTML basique sera donc le suivant :

index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Unofficial Dark Souls</title>

    <link rel="stylesheet" href="css/main.css">
</head>
<body>

<header id="main-header">
    <span id="header-title">Dark Souls</span>
</header>

<div id="main-wrapper">

    <div id="main-content">

        <section>

            <article>
                <h1>Article 1</h1>
                <p>
                    Contenu de l'article
                </p>
            </article>

            <article>
                <h1>Article 2</h1>
                <p>
                    Contenu de l'article
                </p>
            </article>

        </section>

    </div>

</div>

<footer id="main-footer">
    Ce site n'est pas officiel : c'est juste pour apprendre en s'amusant.
</footer>

</body>
</html>

Et pour mieux voir cette structure basique (sans réelle mise en forme) :

main.css
#main-header, #main-wrapper, #main-footer{
    border: 3px solid lightgrey;
}

Résultat

Mise en forme

Nous allons ensuite ajouter du CSS pour structurer la page telle que nous le souhaitons.

De manière à faciliter le positionnement des éléments nous utiliserons flex.

Template CSS :
vous noterez qu'on doit ajouter des informations des style y compris sur les balises html et body

Exercice 01

En modifiant UNIQUEMENT main.css en suivant les consignes ci-avant, faites en sorte que votre page index.html soit affichée comme suit :

Ajout de Contenu

Ressources à utiliser

Images

Pour faire une belle page, nous allons ajouter des images de fond sur nos éléments principaux.

Ces images proviennent du site mobile.alphacoders.com

Police

Nous allons aussi modifier la police de caractères en utilisant une Google Font ( Special Elite), et mettre une petite ombre pour que ce soit joli, même sur un fond sombre.

<style>
    /* cf. la documentation en lie de Google Fonts */
    @import url('https://fonts.googleapis.com/css2?family=Special+Elite&display=swap');
    
    .test-elite-font{
     
        background: radial-gradient(rgb(255, 255, 255), rgb(15, 50, 75)) ;
        padding: 5px;
    
        /* cf. la documentation en lie de Google Fonts */
        font-family: 'Special Elite', cursive; 
    
        color: white;
        font-size: 3em;
        text-shadow: 1px 1px 2px black;
    }
    
</style>
<div class="test-elite-font">
    Dark Souls
</div>
Resultat
Dark Souls

Texte

Enfin, pour que la page ne soit pas vide, on intégrera (par copier/coller dans index.html) le texte contenu dans le fichier DS_descriptif.txt.

Vous pourrez noter que ce fichier contient du texte sans les balises HTML.
Vous devez donc le structurer :

  • L'ensemble du texte est contenu dans une section.
  • Chaque "partie" (Univers, Histoire, ...) correspond à un article
    • Chaque paragraphe correspond à un p

Ce texte est issu de Wikipedia.

Exercice 02

En utilisant ces ressources, modifiez index.html et main.css pour obtenir la page suivante. N'oubliez pas la mise en forme du texte et le scrolling

Spoilers

Un système de spoiler est un classique de Javascript dont les but est de masquer des informations sur la page... jusqu'à ce que l'utilisateur décide de les voir. Pour ce faire, l'utilisateur clique sur un bouton qui a pour effet de révéler les informations qui étaient jusqu'alors cachées.

Spoiler Global : un bouton pour les gouverner tous

Dans cette 1ere version d'un système de spoilers, nous allons masquer des éléments en leur donnant un background et une color qui sont les mêmes.

La première étape de votre travail consistera donc à créer une classe CSS spoiler qui définit la même couleur pour les propriétés background et color des éléments ciblés.

Il nous faudra ensuite créer un bouton qui permet de révéler les informations cachées. Dans cette version, un click sur le bouton révèlera tous les spoilers de la page.

La seconde étape consistera à placer le bouton (global) tout en haut du #main-content (puisque sa portée est globale à cet élément).

On peut envisager de nombreuses solutions pour révéler les spoilers. La solution dépend (entre autres) de la manière dont les spoilers ont été masqués.

Dans cette version, pour révéler les spoilers (suite à un click sur le bouton !), nous allons créer une classe spoiler-visible dont la propriété background sera fixée à initial (le fond par défaut du type d'élément).

L'application de la classe spoiler-visible à un spoiler viendra ainsi écraser (le Cascading de CSS) la propriété background du spoiler, ce qui le révèlera.

La dernière étape consistera à créer la classe spoiler-visible, et à écrire le handler du bouton : cette fonction viendra ajouter la classe spoiler-visible à tous les spoiler de la page.

Vous pourrez trouver des informations bien utiles dans votre cours.

Exercice 03

Pour faire les choses proprement, nous allons créer une sorte de petit module qui contiendra le css et le javascript nécessaires au fonctionnement de ces spoilers.

L'arborescence sera la suivante :

exercice_xx
    |
    |-- index.html
    |-- css
          |-- main.css
    |
    |-- modules
          |-- spoilers
                |-- spoilers.css
                |-- spoilers.js
En suivant les consignes, implémentez le spoiler global comme ci-dessous.

Exercice 04

L'étape suivante consiste à faire en sorte qu'il y ait un bouton spoiler par article : un click sur ce bouton ne révèle que les spoilers de l'article visé.

Résultat attendu :

Spoiler Local
Javascript c'est comme le flirt... à un moment, si on veut aller plus loin, il faut aller plus près...
(@Coluche)

Nous allons maintenant nous intéresser à la technique qui consiste à remplacer chaque spoiler par un bouton qui permet de le dévoiler individuellement. Le spoiler est donc au départ totalement invisible, et "remplacé" par son bouton. Un click sur un bouton fera disparaître le bouton, et fera apparaître le spoiler.

La technique va consister à faire précéder chaque spoiler par un bouton qui lui sera dédié. On aura des paires d'éléments du type :

<button class="spoiler-button">spoil</button><span class="spoiler"> texte du spoiler </span>

J'ai ici utilisé un span, mais j'aurais pu utiliser une autre balise (ex. div, p, ...)

La première étape consiste à insérer le code du bouton juste avant chaque spoiler.

La seconde étape consiste à modifier la classe spoiler:
-> enlever la modification du background, et à la place mettre le display à none.

Heureusement, on ne va pas créer un handler de click différent pour chaque bouton en utilisant des id ! (imaginez la complexité avec une page pleine de spoilers...).

La technique va consister à écrire un handler de click générique, qu'on associera dynamiquement à tous les spoiler-button de la page.

Le code du handler consistera à récupérer l'élément situé juste après le bouton (ce sera un spoiler si vous avez bien bossé..), à lui ajouter la classe spoiler-visible, et enfin, à faire disparaitre le bouton su lequel on vient de cliquer.

La troisième étape consiste à récupérer (en Javascript) tous les spoiler-button,
puis à leur associer un handler de click qui :
  • récupère leur prochain voisin (en anglais : "next sibling element") et modifie son CSS (ajout de spoiler-visible).
  • masque le bouton (display: none).

Exercice 05

Implémentez les étapes listées ci-avant pour obtenir :

Greffons

Comme vous avez du le remarquer à l'étape précédente, il est assez fastidieux de coller le code du spoiler-button devant chaque spoiler à la main dans la page.

La bonne nouvelle est qu'on va pouvoir demander à Javascript de le faire à notre place !
(la moins bonne nouvelle est qu'il va falloir que vous les retiriez du code précédent^^)

Étape 1

La première étape va donc consister (si nécessaire) à nettoyer votre code en retirant toutes les balises <button class="spoiler-button">spoil</button>, tout en laissant les <span class="spoiler"> texte du spoiler </span> en place !

Étape 2

La technique que nous allons mettre en oeuvre va consister à greffer les spoiler-buttons dynamiquement en Javascript : l'idée est de transformer les balises qui portent la classe spoiler.

Plus en détails, nous aurons au départ dans le code des :

<span class="spoiler"> texte du spoiler </span>

Notre objectif va être de les transformer (en Javascript) en :

<span> <!-- cet élément est celui d'origine ! -->
    <button class="spoiler-button">spoil</button> <!-- cet élément a été inséré -->
    <span class="spoiler"> texte du spoiler </span> <!-- cet élément est a été inséré (texte copié) -->
</span>

La seconde étape va consister à :
  • Récupérer tous les éléments portant la classe spoiler.
  • Sauvegarder de leur contenu, les vider, et leur retirer la classe spoiler.
  • Greffer (à l'intérieur) un bouton spoiler-button, en lui ajoutant le handler sur le click (le même que précédemment).
  • Greffer (à l'intérieur) un span avec la classe spoiler et contenant ce qui a été sauvegardé précédemment.

Vous aurez besoin du cours : DOM - Modifier la Hiérarchie.

Exercice 06

Implémentez les étapes listées ci-avant pour obtenir la page suivante (cela ressemble à l'exercice précédent, mais ici les boutons sont créés dynamiquement !)

Sidebar

Un autre classique de Javascript est la mise en place d'une barre de navigation sous forme d'un menu. Il s'agit de fournir une sorte de table des matières qui permettra d'atteindre rapidement différentes parties du contenu.

Il est possible de créer ce type de structure "en dur" (en écrivant directement en HTML les différents items du menu de navigation). Cependant, il y a de fortes chances que, si le contenu change, le menu le doive aussi : il y a une forte dépendance entre le contenu et son menu.

Pour éviter d'avoir à gérer cette dépendance "à la main", nous allons créer un script qui va construire automatiquement le menu à partie des informations du contenu. Il s'agira en fait de parcourir la structure HTML du contenu pour récupérer les titres et les ancres qui nous intéressent, et de créer/greffer des éléments qui les représentent (et permettent de les atteindre) dans la barre de navigation.

Extension du Template

Pour pouvoir insérer les éléments du menu, il est plus simple d'ajouter un élément racine dans notre template.

Dans la page créée précédemment (si ce n'est pas déjà fait...), on va insérer l'élément <nav id='#sidebar'></nav> à l'intérieur du #main-wrapper et juste avant le #main-content
NB : cet élément est censé être vide au départ : il sera rempli par notre script.

Le nouveau template HTML est donc le suivant :

index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Unofficial Dark Souls</title>

    <link rel="stylesheet" href="css/main.css">
</head>
<body>

<header id="main-header">
    <span id="header-title">Dark Souls</span>
</header>

<div id="main-wrapper">
    
    <nav id="sidebar"> <!-- On a juste ajouté l'élément qui recevra le menu ! -->
        Sidebar Test
    </nav> 

    <div id="main-content">

        <section>

            ...

        </section>

    </div>

</div>

<footer id="main-footer">
    Ce site n'est pas officiel : c'est juste pour apprendre en s'amusant.
</footer>

</body>
</html>

Puis on modifie le main.css pour que la structure s'affiche correctement.

Voici la structure CSS étendue que nous allons utiliser :
le #main-wrapper contient la #sidebar et le #main-content.

Exercice 07

Faites ces modifications pour obtenir le résultat suivant :

Exercice 08

Créez un nouveau module nommé sidebar (avec sidebar.js et sidebar.css) et intégrez le à votre page pour obtenir le résultat suivant :
-> NB : la sidebar est remplie en dynamique par Javascript !!! <-

Exercice 09

Résultat attendu :

Correction

La correction est --> ici <--