IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Contribuez Discussion :

Diaporama en 3 lignes de code


Sujet :

Contribuez

  1. #1
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 212
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 212
    Par défaut Diaporama en 3 lignes de code

    Je vous propose de réaliser un diaporama avec seulement 3 lignes de code JavaScript, c'est peu mais suffisant.

    Le principe
    On « empile », dans un conteneur, les éléments les uns sur les autres afin que seul le dernier soit visible à l'écran.
    Toutes les x secondes on déplace, « physiquement » dans le DOM, le premier élément en fin de conteneur, en gros on déplace celui du dessous en haut de la pile, c'est ce que fait la méthode Element.append().

    Un petit schéma pour visualiser :
    Nom : diapo-principe.png
Affichages : 433
Taille : 2,8 Ko
    et ainsi de suite ...

    Structure HTML
    On appliquera la structure suivante :
    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    <div id="diapo" class="diapo-cadre">
      <img src="images/image_001.jpg" alt="">
      <img src="images/image_002.jpg" alt="">
      <img src="images/image_003.jpg" alt="">
      <img src="images/image_004.jpg" alt="">
    </div>

    CSS minimum
    Le CSS, hors cosmétique, se résume à :
    Code css : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    .diapo-cadre {
      display: inline-block;
      position: relative;     /* pour servir de référent */
    }
    .diapo-cadre img {
      display: block;         /* supprime l'espace sous les images */
    }
    .diapo-cadre > * + * {    /* tous les enfants directs sauf le 1st */
      position: absolute;
      top: 0;
      left: 0;
    }
    Tous les éléments sont positionnés en absolu, et placés en haut à gauche, à l'exception du premier qui doit rester dans le flux pour donner une dimension au conteneur.

    Les 3 lignes de code
    Les bases sont posées, maintenant reste le code JavaScript à utiliser :
    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    function runDiaporama(idElement) {
      const elemDiapo = document.getElementById(idElement);
      elemDiapo.append(elemDiapo.firstElementChild);
      setTimeout(() => runDiaporama(idElement), 3000);
    }
    Il suffit d'appeler la fonction en passant l'ID de l'élément :
    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    runDiaporama("diapo");

    Voilà qui est suffisant pour réaliser un diaporama sur base de la manipulation du DOM.


    Démo en ligne
    Pour voir celui-ci en action et pour voir également les améliorations possibles, je vous invite à regarder la page en ligne :
    Diaporama en 3 lignes de code


    N’hésitez pas à proposer vos propres effets.

  2. #2
    Membre confirmé
    Homme Profil pro
    Webmaster
    Inscrit en
    Décembre 2021
    Messages
    81
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Décembre 2021
    Messages : 81
    Par défaut
    Salut
    c'est superbe ces codes que tu m'as donné, ils vont tous me servir en fait

    Pour mon problème en fait je cherche à donner l'impression qu'un bouton clignote, j'ai deux images d'un bouton et je cherche à faire l'affichage alternatif des deux, je pense que ton premier code va bien m'aider pour ça

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Retraité
    Inscrit en
    Janvier 2017
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Janvier 2017
    Messages : 8
    Par défaut Bonjour,
    À la recherche d'un mécanisme de diaporama à la fois simple (code HTML, code CSS, code JavaScript) et agréable à utiliser, j'ai débusqué cette excellente solution de NoSmoking, qui répond presque intégralement à mes attentes,
    • le code HTML est on ne peut plus concis,
    • le code CSS l'est aussi (et je ne suis d'ailleurs pas certain d'en comprendre toutes les subtilités, mais il est d'une efficacité remarquable),
    • le code JavaScript (de la page de présentation, où l'on n'est bien sûr plus en 3 lignes) est - pour moi - assez compréhensible, et j'ai même réussi à l'adapter (étonnant, chez moi qui ne réussis absolument pas à pratiquer ce langage).


    J'ai donc remplacé les deux boutons start/stop par un bouton unique (cf. code ci-dessous). Et je souhaiterais carrément le faire disparaître.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    // gestion du bouton start/stop
     
    const oBtns = document.querySelectorAll("button");
    oBtns.forEach((btn) => {
      let action = btn.dataset.action;
     
      btn["on" == action ? "removeAttribute" : "setAttribute"]("disabled", "disabled");
     
      btn.addEventListener("click", (e) => {
        const idDiapo = btn.dataset.diapo;
        if ("on" == action) {
          runDiaporama(idDiapo);
          btn.nextElementSibling?.removeAttribute("disabled");
          action = "off";
        }
        else {
          stopDiaporama(idDiapo);
          btn.previousElementSibling?.removeAttribute("disabled");
          action = "on";
        }
      })
    })
     
    function runDiaporama(idElement) {
      const elemDiapo = document.getElementById(idElement);
      clearTimeout(elemDiapo._timer);
      elemDiapo.append(elemDiapo.firstElementChild);
      elemDiapo.innerTimer = setTimeout(() => runDiaporama(idElement), 3000);
    }
    function stopDiaporama(idElement) {
      const elemDiapo = document.getElementById(idElement);
      clearTimeout(elemDiapo.innerTimer);
    }
    Je m'explique. Les images du diaporama que je souhaite créer remplissent la totalité de l'écran. C'est pour cela que j'ai installé le bouton sur l'image (en haut à gauche, grâce à l'attribut z-index). Un premier clic déclenche le diaporama, et le suivant l'arrête, etc.

    Je voudrais dématérialiser le bouton, et pouvoir cliquer n'importe où sur l'image pour déclencher/arrêter le déroulement du diaporama (l'attribut title de l'image suffirait à en faire comprendre le fonctionnement).

    Mais je suis parvenu à mes limites, et ne trouve pas la solution. Est-ce possible et, si oui, comment ?

    Merci d'avance de m'éclairer.

  4. #4
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 212
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 212
    Par défaut
    j'ai débusqué cette excellente solution de NoSmoking, qui répond presque intégralement à mes attentes,



    J'ai donc remplacé les deux boutons start/stop par un bouton unique (cf. code ci-dessous). Et je souhaiterais carrément le faire disparaître.
    Dans ce cas il te faut mettre l'écouteur directement sur le conteneur et basculer un état à chaque clic, cela peut se gérer simplement avec l'ajout/retrait d'une classe CSS par exemple.

    En substance cela se traduirait par le code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    "use strict";
    const DIAPO_DELAI = 3000;
    const DIAPO_ID = "diapo-fade";
    const DIAPO_ACTIF = "diapo-actif";
     
    function runDiaporama(idElement) {
      const elemDiapo = document.getElementById(idElement);
      elemDiapo.append(elemDiapo.firstElementChild);
      elemDiapo.innerTimer = setTimeout(() => runDiaporama(idElement), DIAPO_DELAI);
    }
     
    const diapo = document.getElementById(DIAPO_ID);
    diapo.addEventListener("click", (e) => {
      if (diapo.classList.contains(DIAPO_ACTIF)) {
        clearTimeout(diapo.innerTimer);
      }
      else {
        runDiaporama(DIAPO_ID);
      }
      diapo.classList.toggle(DIAPO_ACTIF);
    })
    // lance le diaporama
    setTimeout(() => diapo.click(), DIAPO_DELAI);
    À toi de jouer.

  5. #5
    Nouveau membre du Club
    Homme Profil pro
    Retraité
    Inscrit en
    Janvier 2017
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Janvier 2017
    Messages : 8
    Par défaut Bonjour NoSmoking
    Tout d'abord merci pour ta réactivité.
    Merci aussi pour ta solution qui répond (presque) exactement à mon souhait.
    Juste un petit détail : c'est bien l'avant-dernière image de la pile qui s'affiche (comme prévu). Mais le diaporama ne démarre pas tout seul : il faut cliquer sur l'image pour le démarrer. Peut-on y faire quelque chose ?

  6. #6
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 212
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 212
    Par défaut
    Mais le diaporama ne démarre pas tout seul : il faut cliquer sur l'image pour le démarrer. Peut-on y faire quelque chose ?
    c'est ce que fait cette ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    // lance le diaporama
    setTimeout(() => diapo.click(), DIAPO_DELAI);

  7. #7
    Nouveau membre du Club
    Homme Profil pro
    Retraité
    Inscrit en
    Janvier 2017
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Janvier 2017
    Messages : 8
    Par défaut
    J'ai bien inséré cette ligne dans le script. Néanmoins, à l'ouverture de la page diaporama, on est positionné sur la première image prévue (pas de problème), mais elle reste fixe et le diaporama ne démarre pas.

    Nota : je ne voudrais pas polluer ce sujet avec mes difficultés. Il serait peut-être pertinent de les splitter dans un sujet dédié ?

  8. #8
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 212
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 212
    Par défaut
    Nota : je ne voudrais pas polluer ce sujet avec mes difficultés. Il serait peut-être pertinent de les splitter dans un sujet dédié ?
    Tes questionnements ont tout à fait leur place dans ce fil.

    J'ai bien inséré cette ligne dans le script. Néanmoins, à l'ouverture de la page diaporama, on est positionné sur la première image prévue (pas de problème), mais elle reste fixe et le diaporama ne démarre pas.
    Où est placé ton script ?

    Il faut le placer en fin de page juste avant la balise de fin du body, </body>, ou l'encapsuler dans un DOMContentLoaded comme suit :
    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    <script>
    "use strict";
    document.addEventListener("DOMContentLoaded", () => {
      const DIAPO_DELAI = 3000;
      const DIAPO_ID = "diapo-fade";
      const DIAPO_ACTIF = "diapo-actif";
     
      function runDiaporama(idElement) {
        const elemDiapo = document.getElementById(idElement);
        elemDiapo.append(elemDiapo.firstElementChild);
        elemDiapo.innerTimer = setTimeout(() => runDiaporama(idElement), DIAPO_DELAI);
      }
     
      const diapo = document.getElementById(DIAPO_ID);
      diapo.addEventListener("click", (e) => {
        if (diapo.classList.contains(DIAPO_ACTIF)) {
          clearTimeout(diapo.innerTimer);
        }
        else {
          runDiaporama(DIAPO_ID);
        }
        diapo.classList.toggle(DIAPO_ACTIF);
      })
      // lance le diaporama
      setTimeout(() => diapo.click(), DIAPO_DELAI);
    });
    </script>

    Ressource :

  9. #9
    Nouveau membre du Club
    Homme Profil pro
    Retraité
    Inscrit en
    Janvier 2017
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Janvier 2017
    Messages : 8
    Par défaut
    Je l'ai bien installé en fin de <body>.

    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    <!DOCTYPE html>
    <html lang="fr">
    <head>
    <title>Diaporama en 3 lignes de code</title>
    <link rel="stylesheet" type="text/css" href="Diaporama.css">
    </head>
    <body>
    <div id="diapo-fade" class="diapo-cadre diapo-actif">
    <img src="image03.jpg" loading="lazy" alt="">
    <img src="image04.jpg" loading="lazy" alt="">
    <img src="image05.jpg" loading="lazy" alt="">
    <img src="image06.jpg" loading="lazy" alt="">
    <img src="image01.jpg" loading="lazy" alt="">
    <img src="image02.jpg" loading="lazy" alt="">
    </div>
    <script src="Diaporama.js"></script>
    </body></html>

  10. #10
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 212
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 212
    Par défaut
    La cause est que tu affectes, dans le HTML, la classe diapo-actif au conteneur
    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    <div id="diapo-fade" class="diapo-cadre diapo-actif">
    ... il faut laisser le script gérer l'ajout/retrait de celle-ci.

    Supprime cette classe et tout devrait rentrer dans l'ordre
    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    <div id="diapo-fade" class="diapo-cadre"><!-- exit [diapo-actif] -->

  11. #11
    Nouveau membre du Club
    Homme Profil pro
    Retraité
    Inscrit en
    Janvier 2017
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Janvier 2017
    Messages : 8
    Par défaut
    Impeccable ! Je te remercie chaleureusement pour ton accompagnement.

    Pour diapo-actif, tu avais parlé de classe, et je pensais donc qu'il fallait l'affecter au conteneur. En fait, j'ignorais qu'on pouvait appeler classe une constante interne au script.

    Merci encore, et à bientôt peut-être.

  12. #12
    Expert confirmé
    Avatar de mathieu
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    10 698
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 10 698
    Par défaut
    les classes css sont des classes utilisées dans les fichiers css pour appliquer des effets a des balises :
    https://developer.mozilla.org/fr/doc...lass_selectors

    ensuite ces classes sont appliquées a des balises avec l'attribut "class". cet attribut peut être défini directement dans le code html ou alors le code javascript peut modifier cet attribut et c'est ce qu'il se passe dans le code de NoSmoking.

  13. #13
    Nouveau membre du Club
    Homme Profil pro
    Retraité
    Inscrit en
    Janvier 2017
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Janvier 2017
    Messages : 8
    Par défaut Bonsoir mathieu,
    Merci pour ces éclaircissements.
    En rédigeant mon message ci-dessus, j'avais conscience de mal m'exprimer...

  14. #14
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 212
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 212
    Par défaut Complément d'information
    Citation Envoyé par Dylav
    Pour diapo-actif, tu avais parlé de classe, et je pensais donc qu'il fallait l'affecter au conteneur. En fait, j'ignorais qu'on pouvait appeler classe une constante interne au script.
    pour essayer de lever l’ambiguïté j'ai ajouté CSS à classe dans le texte, « l'ajout/retrait d'une classe CSS par exemple ».

    On aurait tout aussi bien pu utiliser une variable, diapoActif par exemple, permettant de gérer l'état du diaporama, cela aurait peut-être été moins confus.
    Le code serait dans ce cas le suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    "use strict";
    const DIAPO_DELAI = 3000;
    const DIAPO_ID = "diapo-fade";
    //const DIAPO_ACTIF = "diapo-actif";
    let diapoActif = false;
     
    function runDiaporama(idElement) {
      const elemDiapo = document.getElementById(idElement);
      elemDiapo.append(elemDiapo.firstElementChild);
      elemDiapo.innerTimer = setTimeout(() => runDiaporama(idElement), DIAPO_DELAI);
    }
    const diapo = document.getElementById(DIAPO_ID);
    diapo.addEventListener("click", (e) => {
      //if (diapo.classList.contains(DIAPO_ACTIF)) {
      if (diapoActif) {
        clearTimeout(diapo.innerTimer);
      }
      else {
        runDiaporama(DIAPO_ID);
      }
      //diapo.classList.toggle(DIAPO_ACTIF);
      diapoActif = !diapoActif;   // inversion de l'état
    })
    // lance le diaporama
    setTimeout(() => diapo.click(), DIAPO_DELAI);
    Mais alors pourquoi utiliser une classe CSS ?

    Cela permet de gérer via le CSS l'aspect d'éléments du diaporama.

    Par exemple, si au survol du conteneur on veut faire apparaître un [] indiquant que l'on peut lancer le diaporama ou, inversement, un [❚❚] pour le mettre en pause, cela est « facile » à gérer en CSS.

    On notera que l'on pourrait également faire la même chose avec les attributs data-xxx.

  15. #15
    Nouveau membre du Club
    Homme Profil pro
    Retraité
    Inscrit en
    Janvier 2017
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Janvier 2017
    Messages : 8
    Par défaut
    Citation Envoyé par NoSmoking Voir le message
    Cela permet de gérer via le CSS l'aspect d'éléments du diaporama.
    Par exemple, si au survol du conteneur on veut faire apparaître un [] indiquant que l'on peut lancer le diaporama ou, inversement, un [❚❚] pour le mettre en pause, cela est « facile » à gérer en CSS.
    Là, tu me tends une perche tentante. Mais, vu que mon conteneur est pleine page et que je ne souhaite pas voir apparaître ces boutons en permanence, je crois que je vais en rester à la solution actuelle, qui répond exactement à mes souhaits. J'ai même enlevé l'attribut title des balises <img>...

Discussions similaires

  1. [LG]Traduction de 5 lignes de code
    Par barthelv dans le forum Langage
    Réponses: 2
    Dernier message: 14/01/2005, 11h13
  2. Comptabiliser les lignes de code d'un projet
    Par JPigKeud dans le forum Qualimétrie
    Réponses: 5
    Dernier message: 07/01/2005, 14h09
  3. [Debutant(e)]ligne de code sous eclipse
    Par skywalker3 dans le forum Eclipse Java
    Réponses: 1
    Dernier message: 05/01/2005, 17h37
  4. [netbeans][Linux] Nombre de lignes de codes
    Par sylvain_neus dans le forum NetBeans
    Réponses: 5
    Dernier message: 13/08/2004, 10h09
  5. Calculeur de ligne de code
    Par Bernybon dans le forum Autres éditeurs
    Réponses: 9
    Dernier message: 05/03/2004, 16h29

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo