Un carrousel XXL qui s’adapte (plugin scrollide)

Je continue mon perfectionnement (apprentissage) jQuery et pour cela je revisite les classiques des plugins. Cette fois on s’attaque au carrousel … Comment ça encore un ? On n’a jamais assez de carrousel à disposition! Et puis c’est un bon apprentissage.

Pour rendre cette article un peu plus agréable à lire, l’ami Sam m’a donné une idée avec son site sur lequel il doit publier des interviews, même si on n’en a pas encore vu la couleur. Donc je vais (essayer) de rédiger ce tutoriel comme un interview, j’ai trouvé quelqu’un pour poser des questions sur le plugin et je me ferai une joie de lui répondre.

Le testeur : Mais pourquoi un nouveau plugin de carrousel, comme si il n’y en avait pas assez ? Et d’où vient son nom ’scrollide’ ?

Virtuous : Et pourquoi pas ? Développer son plugin c’est l’assurance d’un plugin optimisé pour son besoin (quand il est bien fait ;) ).
Pour le nom, j’ai eu un éclair de génie, j’ai fusionné scroll et slide, scrollide…

Le testeur : Euh mouai… Et qu’est ce qu’il a d’original ce carrousel ?

Virtuous : L’idée de départ est un carrousel dont le cadre serait la pleine largeur de la page et d’afficher un seul élément à la fois. Pour cela ils est possible de forcer l’espacement des éléments exagérément pour être sûr qu’un seul élément s’affiche, mais l’effet ne serait pas très agréable avec trop d’espacement pour rien, aussi dans ce plugin tout s’adapte. Ensuite un point important est que les puces qui permettent de naviguer entre les éléments sont générées par javascript, inutile de les écrire dans le HTML et de les positionner. Et le top, c’est le tooltip qui met en exergue le texte de votre choix de chaque élément pour l’identifier.

Le testeur : Ouai en gros c’est un carrousel comme les autres… Mais est ce qu’il y a une démonstration pour se faire une idée plus précise ?

Virtuous : Bien entendu, voici la démonstration
Et le plugin

Le testeur : Oh en plus vous avez mis du CSS3 dans l’exemple. Peut-on voir la struture HTML de base ?

Virtuous : Oui ça en jette toujours le font-face. Pour la structure, je vais vous présenter la structure de base :


C’est très simple, ici ‘container’ joue le rôle de positionneur. La div ’slider’ sera notre bloc conteneur et qui se déplacera, les div qu’il contient étant chacune un élément qui s’affiche tour à tour. Les boutons sont à placer de chaque côté de la div conteneur. A noter que j’ai donné des id et class dans mon exemple, mais vous pouvez choisir celles que vous voulez sans toucher au plugin.

Le testeur : C’est bien beau tout ça, mais quelles sont les classes générées si je veux customiser mes boutons et autres, à quoi doit ressembler mon CSS ?

Virtuous : Certaines classes sont générées par la javascript, je vais donc vous indiquer lesquelles et présenter le CSS minimum requis pour faire fonctionner le plugin.

body { overflow-x:hidden; } /*Permet de masquer le scroll horizontal de la page*/
#container { /*Ce bloc dont vous pouvez choisir le nom, est l'élément positionneur*/
	width:970px; /*pour l'exemple*/
	margin:0 auto; /*le plugin est fait pour les structures centrées!*/
	position:relative; /*Important pour la position*/
}
#container a.droite,
#container a.gauche { /*Les liens dont le nom est au choix*/
	position:absolute; /*Plus faciles à positionner*/
	top:220px; /*pour l'exemple*/
	z-index:10; /*A gérer suivant vos besoins*/
}
#container a.droite {
	right:0; /*Positionne le lien à droite*/
}
#slider { /*Ce bloc dont vous pouvez choisir le nom, est l'élément conteneur*/
	position:absolute; /*Il va se déplacer!*/
	float:left;
}
.diapo { /*Ce bloc dont vous pouvez choisir le nom, sera la référence pour chaque fenêtre*/
	width:970px; /*pour l'exemple*/
	height:450px;  /*pour l'exemple*/
}
ul.lister { /*Liste générée par le javascript pour les puces*/
	position:absolute; /*Important pour le positionnement*/
	left:0; /*facultatif puisque la liste est repositionnée au centre*/
	top:400px; /*Ajoutez la hauteur que vous voulez*/
	z-index:9; /*A gérer suivant votre besoin*/
}
.lister li { /*Listes générées par le javascript*/
	float:left; /*Important pour leurs positionnements*/
	list-style:none; /*De préférence*/
	margin-right:10px; /*Pour l'exemple, géré selon le besoin*/
	position:relative; /*Important pour positionner le tooltip*/
	width:26px; /*Pour l'exemple*/
	height:26px; /*Pour l'exemple*/
	background:url(../images/puce.png) top no-repeat; /*Pour l'exemple*/
	cursor:pointer; /*Pour donner l'effet 'lien'*/
}
.lister li span { /*Va afficher le texte pris dans la fenêtre que vous avez choisi en variable (h2 par défaut)*/
	position:absolute; /*Important pour le positionnement*/
	width:100px; /*Pour l'exemple*/
	bottom:30px; /*Pour l'exemple*/
	padding:5px 10px; /*Pour l'exemple*/
	background:#be997f; /*Pour l'exemple*/
	text-align:center; /*Pour l'exemple*/
	color:#fff; /*Pour l'exemple*/
}
.lister li.current { /*Cette class est ajoutée à la puce dont la fenêtre est affichée*/
	background-position:bottom;
}

Voilà ce qu’il y a à savoir pour une configuration minimale. après vous pouvez habiller à votre goût.

Le testeur : Ok, et peut-on avoir un aperçu du javascript ? Je parie que c’est un gros fouilli!

Virtuous : C’est vrai que ce n’est pas organisé de façon optimum, mais j’espère que ça vous semblera clair, je vais commenter les parties importantes.

jQuery.fn.scrollide = function(options) { /*Initialise la fonction*/
	var defaults = { /*Variable par défaut*/
		cible: "h2" /*Référence de ce qui sera affiché dans le tooltip des puces*/
	};

	var opts = jQuery.extend(defaults, options);

	$(this).children("div").wrap("

"); /*Pour chaque bloc, on créé une enveloppe qui va positionner la suivante hors du cadre de la fenêtre*/

	var diapos = $(this).children("div").children("div").length;
	var largeur = $(this).children("div").children("div").width();

	var decalage = ($(window).width() - largeur)/2; /*L'espace entre le bord du bloc et le bord de la fenêtre*/
	var wrap = largeur + decalage + 10;

	$(this).children("div").css({width : wrap});

	var largeurTot = diapos*wrap;
	$(this).css({width : largeurTot}); /*Défnit la largeur totale du bloc conteneur*/

	var current = 0;
	var element = $(this);
	var elementParent = $(this).parent().parent();

	$("

").prependTo(elementParent); /*On génère la liste des puces*/
	for (i = 0; i < diapos; i++) {
		var textes = $(".diapo:eq("+ i +") "+ opts.cible +"").text();
		$("ul.lister").append("
  • "+ textes +"
  • "); /*On injecte le contenu voulu pour le tooltip*/ } var ulLargeur = $("ul.lister").width(); var posList = (($(elementParent).width())/2) - (ulLargeur/2); $("ul.lister").css({left : posList}); /*On positionne la liste au centre*/ /*Fonctionnement du tooltip*/ var toolLargeur = $("li span").width(); $("ul.lister li span").hide().css({left : -(toolLargeur/2)}); $("ul.lister li").hover(function(){ $(this).find("span").fadeIn(); },function(){ $(this).find("span").stop(true,true).fadeOut(); }); $("ul.lister li:eq("+ current +")").addClass("current"); var prevBtn = $(this).prev("a"); var nextBtn = $(this).next("a"); $(prevBtn).hide(); /*Ce bouton est toujours caché à l'initialisation*/ $(prevBtn).click(function(){ /*Pour le clique gauche*/ if (current > 0) { current--; if (current == 0) { $(this).fadeOut(); } if (current < diapos - 1) { $(nextBtn).fadeIn(); } $(element).animate({left : '+=' + wrap},500); $("ul.lister li").removeClass("current"); $("ul.lister li:eq("+ current +")").addClass("current"); } }); $(nextBtn).click(function(){ /*Pour le clique droit*/ if (current < diapos - 1) { current++; if (current == diapos - 1) { $(this).fadeOut(); } if (current > 0) { $(prevBtn).fadeIn(); } $(element).animate({left : '-=' + wrap},500); $("ul.lister li").removeClass("current"); $("ul.lister li:eq("+ current +")").addClass("current"); } }); $("ul.lister li").click(function(){ /*Pour l'utilisation des puces*/ var attr = $(this).attr("class"); current = attr; if (current == 0) { $(prevBtn).fadeOut(); } if (current < diapos - 1) { $(nextBtn).fadeIn(); } if (current == diapos - 1) { $(nextBtn).fadeOut(); } if (current > 0) { $(prevBtn).fadeIn(); } $(element).animate({left : attr*-wrap},500); $("ul.lister li").removeClass("current"); $(this).addClass("current"); }); };

    Voilà pour le javascript.

    Le testeur : C’est pas très bien expliqué tout ça, enfin bref. Comment fait-on pour appeler cette fonction scrollide et surtout gérer la variable du tooltip ?

    Virtuous : Bonne question! C’est tout simple, voici ce que vous devez mettre dans votre page :

    $(document).ready(function(){
    	$("#slider").scrollide({
    		cible: "h3"
    	});
    });

    Dans l’exemple on a ciblé les h3 de chaque bloc pour les injecter dans les tooltips des puces. (Pour rappel c’est h2 par défaut).

    Voilà pour l’explication du fonctionnement du plugin, j’espère que ce n’est pas trop confus. C’est loin d’être parfait, mais ça fonctionne (testé sur firefox 3.6, le dernier chrome et safari, ainsi que Opera 10.52).

    Vous aurez deviné que le testeur était autre que moi-même. quelqu’un se prêtera peut etre au jeu la prochaine fois ? :p

    Le prochain article est déjà en chantier, alors à bientôt pour de nouvelles aventures avec jQuery!

    10 réponses à “Un carrousel XXL qui s’adapte (plugin scrollide)”

    1. 1

      Salut,

      très belle réalisation une fois de plus, cependant, en 1024 les flèches de navigation sont bouffées (FF3.6.4 sur Mac).

      StrangeBlackHole

      • 1.1
        admin dit :

        Merci beaucoup!
        je ne pensais pas que quelqu’un viendrait voir l’article avant que j’ai fini de le rédiger, et que j’ai posté le lien sur Twitter et co. Désolé, ça ne fait pas très sérieux… :p
        Pour l’affichage de mon exemple en effet il est optimisé pour du 1200 ou plus, mais le positionnement de ces boutons se gère dans le CSS donc tout à fait adaptable à vos envies et besoins. :)

        Merci encore, a bientôt pour la fin de l’article écrit!

    2. 2
      sebastien dit :

      Ton blog est vraiment très bien, j’aime beaucoup tes articles. Sur celui-là un truc me parait pas clair. J’avais crut comprendre que le slideshow faisait la largeur de la page et donc que le slideshow devenait plus peit quand la fenetre devenait plus petite…mais en fait non. Si ?

      • 2.1
        admin dit :

        Tu veux dire que quand on ‘resize’ la page, le carrousel s’adapte ?
        Et bien non… Et je comprends ta déception car le titre est mensonger dans un sens… Je voulais dire qui s’adapte à la page quand tu arrives dessus. Il est assez rare de recadrer ta fenêtre pendant la navigation.
        Cependant cette option est possible et je rajouterai un petit .resize() .

        Merci et à bientôt.

    3. 3
      • 3.1
        admin dit :

        Personnellement, je n’utilise jamais cette fonction c’est pour ça que ça ne m’a pas effleuré de la mettre, mais je le ferai. Ce blog est un peu bancal… J’ai des idées de refontes, encore faut-il trouver le temps. :)

      • 3.2
        admin dit :

        Et voilà, j’ai ajouté cette option.
        J’essaierai de mettre mon nez dedans pour le traduire… :p

    4. 4
      photos dit :

      “je vais commenter les parties importantes”, euh !?

    5. 5

      I suggest adding a “google+” button for the blog!