Créer un slideshow manuel en jQuery

Pour ce premier tutoriel jQuery, je vous propose de suivre la création et comprendre la logique en jQuery d’un slideshow manuel. J’entends pas “slideshow manuel” une suite de slides dont l’animation de l’une à l’autre se fait manuellement, par un clic sur un bouton ou l’utilisation des flèches clavier.

Je vais concentrer ce tutoriel sur le code jQuery: il est nécessaire de connaître les bases du HTML (ici, HTML5) du CSS et même du Javascript. La démo est volontairement stylisée très simplement, permettant à tout-un-chacun de modifier le code HTML et CSS sans y être perdu.

Démonstration et téléchargement

Démonstration: cliquez ici pour voir le résultat final

Téléchargement: cliquez ici pour télécharger le projet complet (.zip, 38ko)

L’objectif

Vous créez le site web d’une entreprise et listez les services que cette dernière propose. Au lieu de lister ces services les uns en dessous des autres, nous allons créer un slideshow manuel qui permettra de n’afficher qu’un seul service à la fois, et de naviguer d’un service à l’autre grace à des liens en haut de page.

Si l’utilisateur n’a pas activé le javascript, les services sont listés les uns en dessous des autres.

La structure HTML

La structure de notre page est très simple: un titre h1 avec fait office de “navigateur” (que j’appellerai navigator par la suite), et une <section id=”#services”> contient le contenu des slides. Dans cette <section>, chaque slide correspond a un <article>.

Voyez l’extrait suivant pour mieux comprendre…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
&lt;h1 id="navigator"&gt;Cliquez ici pour naviguer vers la &lt;a class="active" href="#premiere"&gt;première slide&lt;/a&gt;, &lt;a href="#deuxieme"&gt;la deuxième&lt;/a&gt; ou &lt;a href="#troisieme"&gt;la troisième&lt;/a&gt;.&lt;/h1&gt;
&lt;section&gt;
    &lt;article id="premiere" class="active"&gt;
        &lt;h1&gt;Titre de la première&lt;/h1&gt;
        &lt;p&gt;Contenu de la première slide&lt;/p&gt;
    &lt;/article&gt;
    &lt;article id="deuxième"&gt;
        &lt;h1&gt;Titre de la première&lt;/h1&gt;
        &lt;p&gt;Contenu de la première slide&lt;/p&gt;
    &lt;/article&gt;
    &lt;article id="troisième"&gt;
        &lt;h1&gt;Titre de la troisième slide&lt;/h1&gt;
        &lt;p&gt;Contenu de la troisième slide&lt;/p&gt;
    &lt;/article&gt;
&lt;/section&gt;

Notez que l’attribut href de chaque lien dans le navigator pointe vers l’id d’une slide dans #services. Cela permet aux utilisateurs n’ayant pas le javascript activé de naviguer automatiquement vers le bon <article> lors d’un clic sur un lien du navigator.

Vous remarquerez la class=”active” pour le premier lien dans le navigator, ainsi que pour la première slide. Cela nous permettra plus tard d’afficher la slide par défaut et cacher les autres slides. Ainsi, si vous voulez afficher par défaut la dernière slide, il suffit d’ajouter la class=”active” au lien dans le navigator ainsi qu’au bon <article>.

La stylisation CSS

Après avoir défini la structure HTML, embellissons la un peu. Le design n’est pas le point important de ce tutoriel, je vous laisse donc décorer le navigator ou les slides comme vous le souhaitez.

Pour faire fonctionner ce script, il est cependant nécessaire de définir deux propriétés indispensables pour les <article> de la <section id=”services”>: ils doivent avoir une largeur définie, et overflow:hidden. En effet, nous allons ensuite déplacer toutes les slides (sauf celle qui sera visible par défaut) hors du cadre #services, il nous faut donc définir la propriété CSS overflow:hidden pour pouvoir cacher les éléments ne sont pas positionnés dans le cadre visible.

Dernière propriété indispensable, cette fois pour la <section id=”services”>: sa position doit être relative pour pouvoir ensuite placer correctement ses enfants <article>.

Mis à part ces trois propriétés indispensables, vous pouvez styliser la liste des slides comme bon vous semble. Vous pouvez aussi définir une taille précise pour les slides <article>, de préférence de la même taille (ou inférieure) à la largeur attribuée au container #services.

N’oubliez pas de styliser la classe .active du #navigator a pour différencier le lien représentant la slide actuellement visible des autres. Pensez également que, pour l’instant, vous voyez la page comme si l’utilisateur n’a pas activé le javascript (certes, peu d’utilisateurs, mais créons des sites accessibles à tous).

La logique Javascript et jQuery

Bon, vous voila avec une jolie page listant les services (ou images, projets, peu importe…) les uns en dessous des autres. Notre code jQuery va se charger de déplacer les slides, définir une hauteur au container #services, et se charger de l’animation lors du clic sur un lien dans le navigator.

Positionnement des slides

Premièrement, il nous faut déplacer les slides (sauf celle par défaut) hors du cadre en leur attribuant une position:absolute, et n’afficher que la slide ayant la class=”active” (vous vous souvenez ?).

Et parce qu’un bon dessin vaut mieux qu’un long discours, voilà un avant et après notre (futur) code.

Avant et après l'intervention de notre code javascript

Avant et après l'intervention de notre code javascript

Nous accomplissons cela très simplement en jQuery. Regardez plutôt le code suivant…

1
2
$('#services article').css({"position":"absolute"});
$('#services article').not('.active').css({"left":"1200px"});

Tous nos <article> de la <section id=”services”> prennent une position:absolute; et on les déplace tous (sauf celui ayant la class=”active”) de 1200px vers la droite (donc à 1200px du point de référence à gauche). Ainsi, étant donné que le container #services a une largeur définie et un overflow:hidden, on ne les voit plus… mais ils sont toujours bel et bien là, hors du cadre de visibilité.

Notez ici l’intérêt d’avoir défini une class=”active” à l’<article> que l’on souhaite voir par défaut au chargement de la page. Le .not(‘.active’) (plus d’infos sur .not()) permet d’exclure de notre sélection l’<article> ayant cette classe, et de déplacer tous les autres <article> hors du cadre. On demande à jQuery de sélectionner tous les<article> de #services, puis d’ôter de cette sélection celui ayant la classe .active, tout simplement! Certains opteront pour l’utilisation de .eq(0) pour sélectionner le premier <article>, mais l’utilisation d’une classe CSS permet de filtrer notre sélection plus librement.

Définir une hauteur au container #services

Tous les <article> qui composent la <section id=”services”> sont en position absolue: cette <section> n’a donc pour l’instant pas de hauteur définie, donc rien n’est visible. Il nous faut donc lui donner une height en fonction de la slide la plus grande.

Voila le code…

1
2
3
4
5
6
var taller_service = 0;
$('#services article').each(function(){
    var service_height = $(this).height();
    if (service_height &gt; taller_service) { taller_service = service_height; }
});
$('.services #services').height(taller_service + 70);

Petites explications sur ce code: pour chaque slide <article>, on analyse sa taille en hauteur. Si cette taille est supérieure à une variable taller_service (initialement définie à 0), cette variable prend pour valeur la taille de la slide analysée. Après analyse de toutes les slides, on change la hauteur du container #services en taller_service.

Notez que j’ajoute 70 a cette variable, permettant ainsi d’avoir une petite marge de 70px en dessous du container #services. Vous pouvez supprimer ou modifier cette valeur à votre souhait.

Animer les slides

Lier le clic sur un lien dans #navigator à l’animation des slides

Nos slides sont cachées, notre container #services a une hauteur, la slide avec une class=”active” est visible… mais il manque l’interaction! Notre navigator n’a aucun effet pour l’instant.

1
2
3
4
5
6
7
$('#navigator a').click(function(e){
    if (!$(this).hasClass('active') &amp;&amp; animating == 0) {
        var service_target = $(this).attr('href').replace('#','');
        changeslide(service_target);
        e.preventDefault();
    }
});

C’est assez explicite: lorsque l’on clique sur un lien du navigator (#navigator a), on vérifie d’abord si le lien cliqué n’a pas la classe CSS .active (car si il l’a, la slide correspondante au lien cliqué est déjà visible!) et si la variable animating est égale à 0 (ce qui nous assure que nous ne sommes pas au milieu d’une animation d’une autre slide).

Si ces deux conditions sont vérifiées, on définit une variable service_target (notre slide cible) en récupérant l’attribut href du lien cliqué ($(this) faisant référence au #navigator a qui vient d’être cliqué), puis on supprime le caractère # de cette variable (.replace(‘#’,”)). Ainsi, si l’on clique sur <a href=”#deuxieme”>, notre variable service_target prendra la valeur “deuxieme“.

Puis, on procède à l’animation de la slide en appelant la fonction changeslide(service_target) que nous créerons dans le prochain chapitre. Ainsi, si l’on clique sur <a href=”#deuxieme”>, jQuery appelera la fonction changeslide(“deuxieme”).

Enfin, la dernière ligne est très importante: elle permet d’annuler la réaction “naturelle” du navigateur lors du clic sur ce lien dans le navigator. Testez votre code sans cette ligne, vous verrez votre navigateur “scroller” vers la position de la slide, car l’on clique sur un lien pointant vers une ancre dans la page. La fonction jQuery .preventDefault() évite ce comportement inacceptable.

Création de la fonction changeslide();

Nous allons alors nous pencher sur la création de notre fonction changeslide(“nom_de_la_slide”) pour automatiser l’animation d’une slide à une autre.

Avant, commençons par une illustration de ce qui se passera en théorie…

Animation des slides

Animation des slides

Rappelez-vous, nous avons auparavant placé les slides (sauf celle visible) à droite, hors du cadre. Nous allons donc déplacer la slide visible sur la gauche, pendant que la slide à faire apparaitre viendra doucement prendre sa place.

Une fois cette animation terminée, l’ancienne slide, sortie du cadre, est invisiblement placée comme les autres, à 1200px à droite.

Voila notre fonction brute de pomme:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function changeslide(service) {
    animating = 1;
    $('#navigator a.active').removeClass('active');
    $('#navigator a[href="#' + service + '"]').addClass('active');
    $('#services .active').animate({"left":"-1200px"},500, function(){
        $(this).removeClass('active').css({"left":"1200px"});
    });
    $('#services #' + service).animate({"left":"0px"},500, function(){
        $(this).addClass('active');
        animating = 0;
    });
}

Vous êtes perdus ? Laissez-moi vous expliquer un peu ce qui se passe dans cette fonction…

D’abord, on change la variable animating à 1. Déjà rencontrée plus haut où, lors d’un clic sur un lien dans #navigator, nous vérifions sa valeur pour autoriser, ou non, l’animation des slides.

Ensuite, on supprime la classe CSS .active du lien de #navigator faisant référence à la slide actuelle , et on donne cette même classe .active au lien dans #navigator sur lequel on vient de cliquer.

Puis, on s’occupe d’animer la slide actuellement visible avec la méthode .animate(). Intéressons-nous un peu à cette méthode très pratique en jQuery, qui permet d’animer des propriétés CSS progressivement (opacité de 1 à 0, position de haut en bas, couleur du rouge au bleu, taille de 100 à 500px, etc…).
La partie {“left”:”-1200px”} est la propriété CSS à changer, 500 est la durée (en millisecondes) pour changer progressivement cette/ces propriété(s) CSS et enfin, la partie function(){ … }); correspond à la fonction qui sera appelée une fois l’animation terminée… donc après 500ms.
Dans notre cas, on anime la slide visible (#services .active) en modifiant progressivement, durant 500ms, sa position jusqu’à -1200px sur la gauche (donc hors du cadre).

Une fois cette animation terminée, on supprime la classe CSS .active de cette slide et on la déplace (cette fois sans animer, avec la méthode jQuery .css()) à 1200px sur la gauche, pour rejoindre ses autres amies slides cachées hors du cadre.

On utilise la même méthode .animate(), cette fois pour la slide à afficher. Pour l’instant à 1200px sur la droite, on créée une animation de 500ms pour faire arriver notre slide désirée à 0px sur la gauche (soit dans notre cadre visible).

Une fois cette animation terminée, on donne à cette nouvelle slide visible la classe CSS .active. On termine par redéfinir notre variable animating à 0, signifiant la fin de l’animation.

Notez la différence entre les fonctions appelées dans les méthodes .animate(), et les autres. jQuery va exécuter l’animation de la slide visible et l’animation de la slide à faire apparaître en même temps, mais les fonctions appelées directement dans la méthode .animate() seront exécutées une fois ces dites-animations terminées. Cela s’avère très pratique lorsque l’on veut, comme ici, savoir si une animation est en cours: notre variable animating prend la valeur 1 lorsque l’on commence les animations, et sa valeur repasse à 0 uniquement lorsque la slide à afficher a été animée. Jetez un oeil à notre code $(‘#navigator a’).click(function(){ … décrit plus haut, et vous comprendrez l’intérêt de la variable animating.

Egalement, notez la concaténation des méthodes en jQuery: $(selecteur).methodeA().methodeB(); revient au même qu’écrire $(selecteur).methodeA; $(selecteur).methodeB(); … mais le sélecteur étant le même, vous pouvez écrire les méthodes à appeler successivement, gagnant ainsi du temps et de l’espace !

Notes

  • Notez bien que je cache et modifie la position des slides en jQuery. Evitez à tout prix d’ajouter un display:none; ou un position :absolute; left:2000px; en CSS, pour une simple et bonne raison: les utilisateurs n’ayant pas activé le javascript ne verront pas les slides que vous avez cachées en CSS. Pensez toujours à tester vos pages avec le javascript désactivé (je commente la ligne <script> dans mon code pour accomplir cela) et vérifiez que les informations importantes sont bien visibles. Stylisez vos pages en CSS en pensant que l’utilisateur n’a pas activé le javascript, et agrémentez d’effets en javascript par la suite.
  • J’ai utilisé une balise <h1 id=”#navigator”> content des liens <a> pour passer d’une slide à l’autre, et ce par choix sémantique: la phrase de navigation faisait également office de titre de page pour mon projet initial, chaque adjectif étant un lien vers la slide correspondante. Si vous préférez créer des onglets ou une simple liste, il vous est sans doute préférable d’utiliser une balise plus sémantique comme <ul> ou <ol>, voire même <nav>.
  • Vous remarquerez que la démonstration permet d’utiliser les flèches clavier gauche et droite pour passer d’une slide à l’autre. Jetez un oeil au code pour comprendre comment j’ai créé cette interaction, et les deux nouvelles fonctions qui en dépendent!

Et voila, un joli slider manuel créé! Vous pouvez désormais l’embellir en CSS et nous faire partager vos créations en commentaires.

Script originalement créée pour la page ‘Services’ du site Spicle.com.

Classé Sous: AstucesDesignGeek Plus

Tags:

A propos de l'auteur: Amoureux de web design et des arts graphiques, Pierre est designer web et print expatrié au Brésil. Designer chez Spicle, il aime partager ses découvertes aux amateurs de HTML, CSS, jQuery et autres web technologies. Retrouvez le sur Twitter (@psaikali) ou découvrez ses créations sur psaikali.com.

FluxCommentaires (0)

URL Trackback

Laisser un commentaire




Ajoutez votre photo à vos commentaires en créant votre Gravatar.