{"id":1356,"date":"2012-08-13T08:46:28","date_gmt":"2012-08-13T06:46:28","guid":{"rendered":"https:\/\/www.creativejuiz.fr\/blog\/?p=1356"},"modified":"2015-10-08T12:59:02","modified_gmt":"2015-10-08T10:59:02","slug":"infinite-slideshow-quelques-lignes-jquery","status":"publish","type":"post","link":"https:\/\/www.creativejuiz.fr\/blog\/tutoriels\/infinite-slideshow-quelques-lignes-jquery","title":{"rendered":"Un Infinite slideshow en quelques lignes de jQuery"},"content":{"rendered":"<p>Un Slideshow sur une page d&rsquo;accueil, c&rsquo;est joli, c&rsquo;est \u00e0 la mode, mais c&rsquo;est souvent lourd \u00e0 int\u00e9grer. Il vous faudra des comp\u00e9tences certaines en jQuery, ou utiliser des plugins d\u00e9j\u00e0 pr\u00eats.<br \/>\nAujourd&rsquo;hui je vous propose un tutoriel pour cr\u00e9er un <em lang=\"en\">infinite slideshow<\/em> en quelques lignes de code.<!--more--><\/p>\n<p>Je vous ai promis, via Twitter, un \u00ab\u00a0dossier-tutoriel\u00a0\u00bb sur la cr\u00e9ation d&rsquo;un slideshow de A \u00e0 Z avec quelques options sympa. Cet article ne fait pas partie du dossier, il n&rsquo;a pas grand chose \u00e0 voir, il s&rsquo;agit simplement de vous pr\u00e9senter une solution enfantine avec une petite dose de HTML, CSS et jQuery.<\/p>\n<h2>L&rsquo;effet <em lang=\"en\">infinite<\/em><\/h2>\n<p>Cet effet donne l&rsquo;impression que votre slideshow ne se termine jamais, il tourne en boucle ind\u00e9finiment sans jamais revenir en arri\u00e8re.<br \/>\nPour se faire, il suffit de placer l&rsquo;image que l&rsquo;on vient de visualiser en fin de liste \u00e0 chaque d\u00e9filement d&rsquo;image, comme sur le sch\u00e9ma suivant :<\/p>\n<p class=\"center\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-1358\" title=\"\" src=\"https:\/\/www.creativejuiz.fr\/blog\/wp-content\/uploads\/2011\/07\/schema-slide.png\" alt=\"L'image 1 qui vient de laisser place \u00e0 l'image 2 passe en fin de liste d'images\" width=\"580\" height=\"300\" srcset=\"https:\/\/www.creativejuiz.fr\/blog\/wp-content\/uploads\/2011\/07\/schema-slide.png 580w, https:\/\/www.creativejuiz.fr\/blog\/wp-content\/uploads\/2011\/07\/schema-slide-300x155.png 300w\" sizes=\"(max-width: 580px) 100vw, 580px\" \/><\/p>\n<p>\u00c0 chaque fois qu&rsquo;une image vient d&rsquo;\u00eatre vue et laisse place \u00e0 l&rsquo;image suivante, elle est plac\u00e9e en fin de liste afin de cr\u00e9er une boucle sans fin.<\/p>\n<h2>La structure de base<\/h2>\n<p>Une division contenant une liste d&rsquo;images suffira pour notre tutoriel.<\/p>\n<pre class=\"code\"><code class=\"language-markup\">&lt;div class=\"slideshow\"&gt;\r\n\t&lt;ul&gt;\r\n\t\t&lt;li&gt;&lt;img src=\"image1.jpg\" alt=\"\" width=\"350\" height=\"200\" \/&gt;&lt;\/li&gt;\r\n\t\t&lt;li&gt;&lt;img src=\"image2.jpg\" alt=\"\" width=\"350\" height=\"200\" \/&gt;&lt;\/li&gt;\r\n\t\t&lt;li&gt;&lt;img src=\"image3.jpg\" alt=\"\" width=\"350\" height=\"200\" \/&gt;&lt;\/li&gt;\r\n\t\t&lt;li&gt;&lt;img src=\"image4.jpg\" alt=\"\" width=\"350\" height=\"200\" \/&gt;&lt;\/li&gt;\r\n\t&lt;\/ul&gt;\r\n&lt;\/div&gt;<\/code><\/pre>\n<p>J&rsquo;utilise ici une liste non ordonn\u00e9e, mais un groupe de <code class=\"element\">figure<\/code> et <code class=\"element\">figcaption<\/code> peut aussi faire l&rsquo;affaire.<br \/>\nJe vous laisse remplir les textes alternatifs \ud83d\ude09<\/p>\n<p>Une fois cette structure en place, il nous faut la styler pour lui donner l&rsquo;apparence du slideshow.<\/p>\n<h2>Les styles de bases<\/h2>\n<p>Notre conteneur doit poss\u00e9der une largeur fixe, et cacher le d\u00e9bordement du contenu.<br \/>\nDans le dossier en cours de pr\u00e9paration dont je parlais en d\u00e9but d&rsquo;article, nous proc\u00e8derons de mani\u00e8re plus \u00ab\u00a0propre\u00a0\u00bb en prenant en compte l&rsquo;activation, ou non, de JavaScript. Mais passons, ici faisons plus simple.<\/p>\n<pre class=\"code\"><code class=\"language-css\">.slideshow {\r\n   width: 350px;\r\n   height: 200px;\r\n   overflow: hidden;\r\n   border: 3px solid #F2F2F2;\r\n}\r\n\r\n.slideshow ul {\r\n    \/* 4 images donc 4 x 100% *\/\r\n   width: 400%;\r\n   height: 200px;\r\n   padding:0; margin:0;\r\n   list-style: none;\r\n}\r\n.slideshow li {\r\n   float: left;\r\n}<\/code><\/pre>\n<p>Rien de compliqu\u00e9 ici : on donne les dimensions aux conteneurs, on annule quelques styles par d\u00e9faut (marges, puces de liste), puis on fait flotter les \u00e9l\u00e9ments. On peut \u00e9galement <a title=\"Autre article sur Creative Juiz sur display:inline-block\" href=\"https:\/\/www.creativejuiz.fr\/blog\/tutoriels\/display-inline-block-une-valeur-trop-peu-utilisee\">utiliser <code>display:inline-block<\/code><\/a>.<\/p>\n<h2>Un petit coup de jQuery<\/h2>\n<p>La premi\u00e8re fois que j&rsquo;avais \u00e9cris ce code, j&rsquo;ai utilis\u00e9 la biblioth\u00e8que jQuery 1.5.1. Quand on voit le poids de la biblioth\u00e8que en version 1.7+, je me suis dit qu&rsquo;on pouvait rester sur la 1.5.<br \/>\nVoici le code, je vous l&rsquo;explique apr\u00e8s.<\/p>\n<pre class=\"code\"><code class=\"language-markup\">&lt;script type=\"text\/javascript\" src=\"https:\/\/ajax.googleapis.com\/ajax\/libs\/jquery\/1.5.1\/jquery.min.js\"&gt;&lt;\/script&gt;\r\n\u00a0\r\n&lt;script type=\"text\/javascript\"&gt;\r\n   $(function(){\r\n      setInterval(function(){\r\n         $(\".slideshow ul\").animate({marginLeft:-350},800,function(){\r\n            $(this).css({marginLeft:0}).find(\"li:last\").after($(this).find(\"li:first\"));\r\n         })\r\n      }, 3500);\r\n   });\r\n&lt;\/script&gt;<\/code><\/pre>\n<h2>Un grand coup d&rsquo;explications<\/h2>\n<p>Voici quelques explications pour les personnes les moins aguerries en jQuery, car le code est court, mais quelque peu condens\u00e9.<\/p>\n<pre class=\"code\"><code class=\"language-javascript\">\r\n   $(function(){\r\n      [\u2026]\r\n   });<\/code><\/pre>\n<p>Cette partie englobant notre fonction permet de v\u00e9rifier que le document est bien charg\u00e9, c&rsquo;est l&rsquo;\u00e9quivalent de <a href=\"http:\/\/api.jquery.com\/ready\/\">la fonction <code>ready()<\/code><\/a>.<\/p>\n<pre class=\"code\"><code class=\"language-javascript\">\r\n   setInterval(function(){\r\n      [\u2026]\r\n   }, 3500);<\/code><\/pre>\n<p>Cette partie permet de d\u00e9finir une action qui va se r\u00e9p\u00e9ter \u00e0 intervalle r\u00e9gulier. <a href=\"http:\/\/www.w3schools.com\/jsref\/met_win_setinterval.asp\">La fonction <code>setInterval()<\/code><\/a> prend en param\u00e8tres une fonction anonyme (ou le nom d&rsquo;une fonction existante), et le d\u00e9lai en milliseconde entre chaque ex\u00e9cution de la fonction. Dans notre cas, nous d\u00e9finissons une fonction anonyme avec <code>function(){}<\/code> et d\u00e9finissons la r\u00e9p\u00e9tition \u00e0 3,5 secondes.<br \/>\nPetite parenth\u00e8se : il arrive tr\u00e8s souvent de croiser la syntaxe <code>var t = setInterval()<\/code>. Cette syntaxe permet l&rsquo;annulation de la r\u00e9p\u00e9tition gr\u00e2ce \u00e0 la fonction <code>clearInterval(t)<\/code>.<\/p>\n<p>Le tron\u00e7on qui va suivre est un peu plus complexe \u00e0 comprendre car il utilise massivement le principe de cha\u00eenage de jQuery. Il faut imaginer qu&rsquo;\u00e0 chaque fois qu&rsquo;un point apparait, on utilise le pr\u00e9c\u00e9dent objet jQuery pour le manipuler.<\/p>\n<p>Exemple :<\/p>\n<pre class=\"code\"><code class=\"language-javascript\">$('ul').find('li').css('color', 'red').filter(':first').css('color','green');<\/code><\/pre>\n<p>Nous commen\u00e7ons par \u00ab\u00a0s\u00e9lectionner\u00a0\u00bb nos \u00e9l\u00e9ments <code class=\"element\">ul<\/code> dans notre document, puis nous ciblons les \u00e9l\u00e9ments <code class=\"element\">li<\/code>, la fonction <code>find()<\/code> nous retourne un objet jQuery, puis nous appliquons un style particulier sur ces \u00e9l\u00e9ments. La fonction <code>css()<\/code> nous retourne le m\u00eame objet jQuery que pr\u00e9c\u00e9demment, ce qui nous permet de le manipuler \u00e0 nouveau et d&rsquo;aller chercher uniquement le premier \u00e9l\u00e9ment <code class=\"element\">li<\/code> gr\u00e2ce \u00e0 la fonction <code>filter()<\/code> qui retourne \u00e9galement un objet jQuery auquel on va appliquer d&rsquo;autres styles, etc.<br \/>\nIl faut savoir que la plupart des fonctions jQuery permettent ainsi le chainage.<\/p>\n<p>Reprenons donc sur ce fameux tron\u00e7on :<\/p>\n<pre class=\"code\"><code class=\"language-javascript\">\r\n $(\".slideshow ul\").animate({marginLeft:-350},800,function(){\r\n   $(this).css({marginLeft:0}).find(\"li:last\").after($(this).find(\"li:first\"));\r\n })<\/code><\/pre>\n<p>Nous commen\u00e7ons par cibler notre <code class=\"element\">ul<\/code> que nous allons faire bouger vers la gauche gr\u00e2ce \u00e0 une animation qui va appliquer une marge n\u00e9gative de 350px en 0,8 secondes (<code>animate(marginLeft:-350, 800)<\/code>). <a href=\"http:\/\/api.jquery.com\/animate\/\">La fonction animate()<\/a> permet d&rsquo;ex\u00e9cuter une fonction de callback, il s&rsquo;agit d&rsquo;une fonction ex\u00e9cut\u00e9e lorsque <code>animate()<\/code> retourne \u00ab\u00a0complete\u00a0\u00bb : quand l&rsquo;animation est termin\u00e9e donc :p<br \/>\nCette fonction de callback, nous la d\u00e9clarons juste apr\u00e8s le param\u00e8tre de dur\u00e9e de l&rsquo;animation.<br \/>\nCette fonction ex\u00e9cute ce qui suit :<\/p>\n<pre class=\"code\"><code class=\"language-javascript\">$(this).css({marginLeft:0}).find(\"li:last\").after($(this).find(\"li:first\"));<\/code><\/pre>\n<p>De quoi se faire plaisir en terme de chainage.<br \/>\n<code>$(this)<\/code> repr\u00e9sente chacun des <code>.slideshow ul<\/code> que pourrait retourner notre objet jQuery (oui, il pourrait y avoir plusieurs slideshow sur votre page).<br \/>\nNous partons donc de notre \u00e9l\u00e9ment <code class=\"element\">ul<\/code> auquel nous supprimons la marge n\u00e9gative r\u00e9cemment attribu\u00e9e par l&rsquo;animation, puis nous allons chercher le dernier <code class=\"element\">li<\/code> de notre liste (<code>find(\"li:last\")<\/code>) et nous y pla\u00e7ons juste apr\u00e8s (<code>after()<\/code>) le premier \u00e9l\u00e9ment de notre liste (<code>$(this).find(\"li:first\")<\/code>).<br \/>\n<a href=\"http:\/\/api.jquery.com\/after\/\">La fonction <code>after()<\/code><\/a> a une syntaxe assez particuli\u00e8re, j&rsquo;en conviens, je vous invite donc \u00e0 lire la documentation pour plus d&rsquo;informations \u00e0 son sujet.<\/p>\n<p>Tout ce morceau de code est ex\u00e9cut\u00e9 quasiment en m\u00eame temps \u00e0 la fin de l&rsquo;animation. \u00c0 chaque d\u00e9filement d&rsquo;un slide, on prend le premier \u00e9l\u00e9ment de la liste, on le place \u00e0 la fin, et on annule la marge n\u00e9gative que l&rsquo;on vient de donner \u00e0 notre liste. C&rsquo;est invisible pour l&rsquo;oeil.<\/p>\n<p>J&rsquo;esp\u00e8re que les explications ne sont pas plus complexes que le code \ud83d\ude00<\/p>\n<p class=\"center\"><a class=\"demonstration\" href=\"\/blog\/doc\/infinite-slideshow\/\">Voir la d\u00e9monstration<\/a><\/p>\n<p class=\"message\">Je vous recommanderais presque de ne pas suivre ce tutoriel pour de la production. En effet, en terme d&rsquo;accessibilit\u00e9 (et m\u00eame d&rsquo;ergonomie) l&rsquo;absence de contr\u00f4le sur l&rsquo;animation est perturbante. (entre autres d\u00e9fauts)<br \/>\nLe prochain dossier devrait prendre en compte ces crit\u00e8res.<br \/>\n\u00c0 venir donc !<\/p>\n<h2>M\u00e9thode 2<\/h2>\n<p>Une seconde m\u00e9thode, assez semblable mais plus simple \u00e0 comprendre, nous a \u00e9t\u00e9 propos\u00e9e par <a href=\"http:\/\/thierrymichel.net\/\">Thierry<\/a>. Je vous place le code jQuery :<\/p>\n<pre class=\"code\"><code class=\"language-javascript\">(function($){  \r\n  setInterval(function(){  \r\n    $(\".slideshow ul li:first-child\").animate({\"margin-left\": -350}, 800, function(){  \r\n        $(this).css(\"margin-left\",0).appendTo(\".slideshow ul\");  \r\n    });  \r\n  }, 3500);  \r\n})(jQuery);<\/code><\/pre>\n<p>Les changements se situent sur le premier s\u00e9lecteur, afin que l&rsquo;animation ne se fasse que sur le premier \u00e9l\u00e9ment de la liste (<code>li:first-child<\/code>).<br \/>\nCelui-ci subit un d\u00e9calage de 350 pixels, les autres <code class=\"element\">li<\/code> suivent le mouvement.<br \/>\nUne fois cette animation termin\u00e9e, la fonction <code>appendTo()<\/code> permet d&rsquo;ins\u00e9rer ce premier \u00e9l\u00e9ment en le pla\u00e7ant \u00e0 la suite des autres \u00e9l\u00e9ments du conteneur (<code>.slideshow ul<\/code>), ici \u00e0 la fin des diff\u00e9rents <code class=\"element\">li<\/code>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Un Slideshow sur une page d&rsquo;accueil, c&rsquo;est joli, c&rsquo;est \u00e0 la mode, mais c&rsquo;est souvent lourd \u00e0 int\u00e9grer. Il vous faudra des comp\u00e9tences certaines en jQuery, ou utiliser des plugins d\u00e9j\u00e0 pr\u00eats. Aujourd&rsquo;hui je vous propose un tutoriel pour cr\u00e9er un infinite slideshow en quelques lignes de code.<\/p>\n","protected":false},"author":4,"featured_media":2826,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_bluesky_dont_syndicate":"","_bluesky_syndication_accounts":"","_bluesky_syndication_text":"","footnotes":""},"categories":[610,9],"tags":[228,366,52,113,15],"coauthors":[597],"class_list":["post-1356","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-javascript","category-tutoriels","tag-astuce","tag-infinite","tag-jquery","tag-slideshow","tag-tutoriel"],"acf":[],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.creativejuiz.fr\/blog\/wp-json\/wp\/v2\/posts\/1356","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.creativejuiz.fr\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.creativejuiz.fr\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.creativejuiz.fr\/blog\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/www.creativejuiz.fr\/blog\/wp-json\/wp\/v2\/comments?post=1356"}],"version-history":[{"count":0,"href":"https:\/\/www.creativejuiz.fr\/blog\/wp-json\/wp\/v2\/posts\/1356\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.creativejuiz.fr\/blog\/wp-json\/wp\/v2\/media\/2826"}],"wp:attachment":[{"href":"https:\/\/www.creativejuiz.fr\/blog\/wp-json\/wp\/v2\/media?parent=1356"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.creativejuiz.fr\/blog\/wp-json\/wp\/v2\/categories?post=1356"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.creativejuiz.fr\/blog\/wp-json\/wp\/v2\/tags?post=1356"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.creativejuiz.fr\/blog\/wp-json\/wp\/v2\/coauthors?post=1356"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}