[JS]Diaporama en 3 lignes de code

NoSmoking

Réalisation d'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 :
schéma

et ainsi de suite ...

Structure HTML

<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

.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.

Les 3 lignes de code

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 en paramètre :

runDiaporama("diapo");

Le résultat

Amélioration

Il faut bien admettre que le résultat est un peu brut, on va donc lui ajouter un effet fade in-out.

L'élément diaporama est maintenant déclaré comme suit :

<div id="diapo-fade" class="diapo-cadre">
  <!-- Les éléments à faire défiler -->
</div>

Pour réaliser cela il convient simplement d'ajouter les règles CSS suivantes :

#diapo-fade > * {             /* tous les enfants directs */
  opacity: 1;
  transition: opacity 1s;
}
#diapo-fade > :last-child {   /* uniquement le dernier enfant direct */
  opacity: 0;
}

On obtient le résultat suivant :

C'est déjà plus agréable, il faut noter que dans cette configuration c'est l'avant dernier élément qui est affiché.
Il faut en tenir compte si l'ordre d'affichage au début est important pour vous.

Quand un élément est au dessus, en dernière position donc, sont opacité est de 0, on voit ainsi l'avant dernier élément. Lorsque cette élément devient à son tour l'avant dernier, suite au déplacement de l'élément du dessous, son opacité passe de 0 à 1 d'où l'effet de fade.

Pour le FUN !

On peut bien évidement combiner les effets.

Ce sont le CSS et votre imagination qui entrent en lice dans ce cas, la fonction JavaScript elle restant la même.

Image #1
Image #2
Image #3
Image #4

Pour ce dernier diaporama la déclaration est la suivante :

<div id="diapo-fun" class="diapo-cadre">
  <!-- Les éléments à faire défiler -->
</div>

Le CSS appliqué sur les éléments devient le suivant :

#diapo-fun > * {
  opacity: 1;
  transition: all 1s;
  transform: scale(1) rotate(360deg);
}
#diapo-fun .inverse {
  transform: scale(1) rotate(-360deg);
}
#diapo-fun > :last-child {
  opacity: 0;
  transform: scale(0) rotate(0);
}

Observations

Voilà ce que l'on peut faire simplement avec la manipulation du DOM et un peu de CSS.

Si ces 3 lignes de code sont encore de trop, vous pouvez regarder de que l'on peut réaliser en pur CSS :

Ressources

Et si vous voulez « dépiler » au lieu « d'empiler » :