JQuery est devenu rapidement un framework de développement javascript indispensable, très pratique que ce soit pour développer de simples fonctionnalités ou des sites complets.

Souvent, lors de la création d’un site internet, on rencontre les mêmes fonctionnalités de base (des rollover sur les images, un menu déroulant, un diaporama …), et pour chacun d’entre eux, il existe quasiment un plugin JQuery qui répond à ces attentes.

Il peut être également utile de développer un plugin pour une fonctionnalité simple mais à laquelle on se trouve souvent confronté et dont on veut maîtriser le fonctionnement.

Mon premier tutoriel s’articulera donc autour de la mise en place d’un plugin JQuery simple: un diaporama Photo.

Diaporama simple avec JQuery

DEMO DOWNLOAD

Introduction

Nous allons donc réaliser un diaporama de photos. Le principe étant que les photos défilent les unes après les autres avec une transition par fondu enchaîné. Nous allons aussi ajouter des boutons de contrôle pour mettre en pause le diaporama, accéder à la photo suivante ou précédente.

Première étape: partie HTML

Avant tout, il convient d’inclure la librairie JQuery dans notre page de test. Vous pouvez la trouver ici : Librairie JQuery

Ensuite, nous allons écrire une page HTML simple avec une liste de photos.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr">
	<head>
		<title>Diaporama Simple JQuery</title>
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

		<!-- Cascading Style Sheets -->
		<link href="page.css" rel="stylesheet" type="text/css" />
		<link href="style.css" rel="stylesheet" type="text/css" />

		<!-- Javascript -->
		<script type="text/javascript" src="js/jquery-1.3.2.min.js"></script>
		<script type="text/javascript" src="js/jquery.diaporama.js"></script>
		<script type="text/javascript" src="js/script.js"></script>
	</head>

	<body>

		<h1>Diaporama Simple</h1>

		<ul class="diaporama">
			<li><img src="img/galerie/image1.jpg" alt="Image 1" /></li>
			<li><img src="img/galerie/image2.jpg" alt="Image 2" /></li>
			<li><img src="img/galerie/image3.jpg" alt="Image 3" /></li>
			<li><img src="img/galerie/image4.jpg" alt="Image 4" /></li>
			<li><img src="img/galerie/image5.jpg" alt="Image 5" /></li>
		</ul>

	</body>

</html>

Deuxième étape: partie CSS

Le principe de base du diaporama est de superposer les images pour ensuite les faire défiler. Nous allons donc créer une feuille de style avec les propriétés suivantes :

.diaporama{
	position:relative;
	width:512px; /* Largeur d'une photo */
	height:288px /* Hauteur d'une photo */
}

.diaporama li{
	list-style-type:none;
	overflow:hidden;
	position:absolute /* Les images seront positionnées toutes au même endroit */
}

.diaporama_controls{
	width:512px;
	margin:3px 0;
	padding:5px;
	clear:both;
	overflow:hidden;
}

.diaporama_controls .btns{
	float:right;
}

.diaporama_controls a{
	font-weight:normal;
	width:10px;
	height:13px;
	text-indent:-9999px;
	display:inline-block;
	margin:0 3px;
}

.diaporama_controls .prev{
	background:url(img/fleches_diapo.png) no-repeat top right;
}

.diaporama_controls .next{
	background:url(img/fleches_diapo.png) no-repeat top left;
}

.diaporama_controls .pause{
	background:url(img/fleches_diapo.png) no-repeat bottom right;
}

.diaporama_controls .play{
	background:url(img/fleches_diapo.png) no-repeat bottom left;
}

Je ne détaillerai pas le contenu de la feuille de style page.css, celle-ci n’est utilisée que pour la mise en page de l’index.html.

Voici le résultat que nous avons pour l’instant :

Diaporama simple avec JQuery

Troisième étape: partie JQuery

Nous allons avoir deux fichiers javascript :

  1. Notre fichier plugin « jquery.diaporama.js« 
  2. Un fichier de script, pour exécuter le diaporama « script.js« 

Instanciation du plugin Diaporama

La fonction Diaporama doit être appelée dans la page html, au chargement de la page, au moyen de la fonction JQuery $(document).ready()

Cet appel sera effectué depuis le fichier script.js :

$(document).ready(function(){

	$(".diaporama").diaporama({
		animationSpeed: "slow",
		delay:2
	});

});

On va éxécuter la fonction diaporama sur tous les éléments qui ont une classe « diaporama ».

Structure du plugin

(function($){ // 1
	$.fn.diaporama = function(options) {

		// 2 Appliquer le diaporama sur chacun des éléments ciblés
		this.each(function(){

		});

		return this;  // 3 Continuer le chainage JQuery
	};
})(jQuery);

Voici la structure de base d’un plugin JQuery :

  1. On utilise function($) pour explicitement dire qu’on va utiliser l’alias « $ » dans notre fonction
  2. La fonction diaporama va être appelée sur un élément ou un ensemble d’éléments. Il convient donc d’éxécuter pour chacun des éléments rencontrés la fonction diaporama
  3. Le chaînage permet de continuer d’appliquer des fonctions à notre sélecteur, par exemple, $(« .diaporama »).diaporama().show.fadeOut() …

Paramètres

Nous allons utiliser différents paramètres pour notre diaporama :

  1. delay: le délai de balayage des images
  2. animationSpeed: la durée de l’effet de transition
  3. controls: affichage des boutons de contrôle

Cela va se traduire dans notre script par :

var defaults = {
	delay: 3,
	animationSpeed: "normal",
	controls:true
};

var options = $.extend(defaults, options);  // 1
  1. $.extend est une fonction JQuery qui permet de créer une variable options à partir, soit de la variable defaults, soit des paramètres spécifiés dans l’appel de la fonction $.fn.diaporama = function(options)
    De ce fait, les paramètres non spécifiés dans l’appel du plugin seront ceux par défaut.

Initialisation

On va maintenant initialiser le diaporama:

  1. Vérifier que la liste contient au moins deux photos
  2. Initialiser nos variables
  3. Lancer la mécanique de rotation d’images
// On attribue à la variable obj, l'objet courant (le diaporama courant)
var obj = $(this);

// On teste si il y a plus d'une image, sinon le diaporama n'est pas nécessaire
if($(obj).find("li").length > 1){

	// On va exécuter la fonction nextElt à chaque intervalle de temps
	var inter = setInterval(function(){nextElt(options)}, (options.delay*1000));

	// On enregistre le sens de rotation
	var sens = "right";

	// Par défaut, le diaporama n'est pas en pause
	var pause = false;

	// On cache tous les éléments de la liste
	$(obj).find("li").hide();

	// Le premier élément s'affiche progressivement et se voit attribuer la classe "active"
	$(obj).find("li:first-child").addClass("active").fadeIn(options.animationSpeed);
}

Si le paramètre controls est défini à true, alors on ajoute les boutons de contrôle:

// On veut ajouter des boutons de contrôle
if(options.controls)
{
	// On insère après la liste un <div> contenant les boutons "précédent", "suivant" et "pause"
	$(obj).after("<div class='diaporama_controls'><div class='btns'><a href='#' class='prev'>Prec.</a> <a href='#' class='pause'>Pause</a> <a href='#' class='next'>Suiv.</a></div></div>");

	// On définit l'action click pour le bouton "précédent"
	// La méthode siblings() permet de trouver les éléments "frères" de l'élément courant
	$(obj).siblings().find(".prev").click(function(){
		// On supprime l'intervalle automatique de transition d'image
		clearInterval(inter);

		// On appelle la fonction qui affiche l'image précédente
		prevElt(options);

		// Si le diaporama n'est pas sur pause, on relance l'affichage automatique
		if(!pause)
			inter = setInterval(function(){prevElt(options)}, (options.delay*1000));

		// On définit le sens à gauche
		sens = "left";
	});

	// On applique la même méthode ou presque au bouton "suivant" (dans l'autre sens)
	$(obj).siblings().find(".next").click(function(){
		clearInterval(inter);
		nextElt(options);
		if(!pause)
			inter = setInterval(function(){nextElt(options)}, (options.delay*1000));
		sens = "right";
	});

	// Si on appuie sur "pause", on définit deux actions
	$(obj).siblings().find(".pause").toggle(

		// On change l'image de fond du bouton via la classe "play"
		function(){
			$(this).removeClass("pause").addClass("play");

			// On supprime l'intervalle
			clearInterval(inter);

			// On positionne le booléen à true
			pause = true;
		},
		function(){

			// On remet l'image originale
			$(this).removeClass("play").addClass("pause");

			// On relance le diaporama dans le sens où il était
			inter = setInterval(function(){ (sens == "right")?nextElt(options):prevElt(options)}, (options.delay*1000));
			pause = false;
		}
	);
}

Ensuite, nous allons développer la fonction qui permet de passer à l’image suivante:

function nextElt(options)
{
	// On cache de manière progressive l'image active
	$(obj).find("li.active").fadeOut(options.animationSpeed);

	// Si l'image active courante n'est pas la dernière image de la liste
	if(!$(obj).find("li.active").is(":last-child"))
	{
		// Alors on cherche l'image suivante (".next()"), on lui ajoute la class "active",
		// et on retire cette classe à l'image précedente (l'ancienne image active)
		$(obj).find("li.active").next().addClass("active").prev().removeClass("active");

		// On affiche la nouvelle image active progressivement
		$(obj).find("li.active").fadeIn(options.animationSpeed);
	}
	// L'image est la dernière de la liste
	else
	{
		// On fait la même chose mais en prenant la première image de la liste via le sélecteur "first-child"
		$(obj).find("li:first-child").addClass("active").fadeIn(options.animationSpeed);
		$(obj).find("li:last-child").removeClass("active");
	}
}

Script final

Et voilà, nous avons à présent tous les éléments dont nous avons besoin pour que le diaporama fonctionne.

Voici le script final diaporama.js :

(function($){
	$.fn.diaporama = function(options) {

		var defaults = {
			delay: 3,
			animationSpeed: "normal",
			controls:true
		};

		var options = $.extend(defaults, options);

		this.each(function(){

			var obj = $(this);

			if($(obj).find("li").length > 1){
				var inter = setInterval(function(){nextElt(options)}, (options.delay*1000));
				var sens = "right";
				var pause = false;

				$(obj).find("li").hide();
				$(obj).find("li:first-child").addClass("active").fadeIn(options.animationSpeed);

				// Controls

				if(options.controls)
				{
					$(obj).after("<div class='diaporama_controls'><div class='btns'><a href='#' class='prev'>Prec.</a> <a href='#' class='pause'>Pause</a> <a href='#' class='next'>Suiv.</a></div></div>");

					$(obj).siblings().find(".prev").click(function(){
						clearInterval(inter);
						prevElt(options);
						if(!pause)
							inter = setInterval(function(){prevElt(options)}, (options.delay*1000));
						sens = "left";
					});

					$(obj).siblings().find(".next").click(function(){
						clearInterval(inter);
						nextElt(options);
						if(!pause)
							inter = setInterval(function(){nextElt(options)}, (options.delay*1000));
						sens = "right";
					});

					$(obj).siblings().find(".pause").toggle(
						function(){
							$(this).removeClass("pause").addClass("play");
							clearInterval(inter);
							pause = true;
						},
						function(){
							$(this).removeClass("play").addClass("pause");
							inter = setInterval(function(){ (sens == "right")?nextElt(options):prevElt(options)}, (options.delay*1000));
							pause = false;
						}
					);
				}

				// Affiche l'élément suivant

				function nextElt(options)
				{
					$(obj).find("li.active").fadeOut(options.animationSpeed);

					if(!$(obj).find("li.active").is(":last-child"))
					{
						$(obj).find("li.active").next().addClass("active").prev().removeClass("active");
						$(obj).find("li.active").fadeIn(options.animationSpeed);

					}
					else
					{
						$(obj).find("li:first-child").addClass("active").fadeIn(options.animationSpeed);
						$(obj).find("li:last-child").removeClass("active");
					}
				}

				// Affiche l'élément précédent

				function prevElt(options)
				{
					$(obj).find("li.active").fadeOut(options.animationSpeed);

					if(!$(obj).find("li.active").is(":first-child"))
					{
						$(obj).find("li.active").prev().addClass("active").next().removeClass("active");
						$(obj).find("li.active").fadeIn(options.animationSpeed);

					}
					else
					{
						$(obj).find("li:last-child").addClass("active").fadeIn(options.animationSpeed);
						$(obj).find("li:first-child").removeClass("active");
					}
				}
			}
		});

		return this;
	};
})(jQuery);

Téléchargements et Démo

La démo est disponible ici.

Les fichiers sources : télécharger les fichiers sources de l’example.

  • Facebook
  • Twitter
  • Digg
  • del.icio.us
  • Netvibes

35 commentaires sur “Tutoriel: Réaliser un diaporama simple avec JQuery”

  1. lucas dit :

    Bonjour,
    merci pour le partage de vos connaissances et de votre travail.
    Je suis en ce moment sur le développement d’un diaporama d’articles sous SPIP et votre plugin bien détaillé me semble adapté à ce que je recherche.

    Une petite question : peut-on ne pas précharger les images (en fait je désire incorporer des éléments video flv par exemple, ou flash swf) afin qu’au changement d’affichage de diapositive la lecture du fichier avi démarre, comme si on venait d’ouvrir la page html contenant ce fichier ?

    Merci pour votre aide.

    Cordialement

    Pascal

  2. Guillaume dit :

    @lucas: Merci de votre intérêt pour mon tutoriel.

    Dans votre cas, il vous faudrait utiliser la librairie Swf Object pour la lecture de flash/flv, modifier en conséquence le plugin pour qu’il puisse detecter le type d’élément (image ou flash) et ainsi pouvoir lancer l’animation automatiquement lorsque l’élément actif est celui où est le flash (via swf object).

    Tout cela est donc bien possible ! Bon courage pour vos développements.

  3. Malou dit :

    Bonjour, et merci beaucoup pour ce Tutoriel.

    Est-il possible (ou plutôt devrais-je dire facile) d’inclure une légende du type 1/6, 2/6, etc.
    Autre chose, où définit-on, le placement des flèches (je voudrai plutôt les placer en haut des images)?

    Merci d’avance

  4. Guillaume dit :

    @Malou: Il est très facile d’inclure une légende, il te suffit d’ajouter le texte de la légende dans le « li » qui contient l’image. Elle sera affichée automatiquement lorsque le « li » sera affiché.

    Les flèches sont par défaut affichées après l’image. Pour changer l’emplacement, il te suffit de changer dans cette ligne:

    $(obj).after("Prec. Pause Suiv.");

    le « .after() » par « .before() » (http://docs.jquery.com/Manipulation/before#content)

    Et le tour est joué ;)

  5. Malou dit :

    Merci mille fois pour cette réponse très claire et très rapide!
    M.

  6. Sofien dit :

    Bonjour,
    j’aimerais savoir si il est possible de réinitialiser le diaporama à la suite d’un changement de contenu ?
    Merci !

  7. Guillaume dit :

    @ Sofien: Oui pas de problème, il te suffit de rappeler la méthode « diaporama() » et cela prendra en compte les nouvelles modifications.

  8. Alex dit :

    Bonjour Guillaume et merci pour ce tutoriel très bien fait et très bien expliqué.
    En fait, j’aimerais savoir s’il était possible de changer les boutons flèches afin de les adapter à ma charte graphique.

    Merci beaucoup !

    Alex

  9. Guillaume dit :

    @Alex: Tout est dans le css ;) Les boutons flèches sont des Sprites CSS, il te suffit donc de créer tes propres images !

  10. carine dit :

    Bonjour,

    Merci pour ce tutoriel pour utile !

    Tout marche très bien, sauf le « next » et « previous ». Lorsque je clique dessus, la page remonte tout en haut comme après un rechargement de page (mon diaporama se trouve bas de page).

    Merci pour votre réponse

  11. Guillaume dit :

    @ Carine : Oui effectivement, il manque un « return false » dans les fonctions de click :

    $(obj).siblings().find(« .next »).click(function(){
    clearInterval(inter);
    nextElt(options);
    if(!pause)
    inter = setInterval(function(){nextElt(options)}, (options.delay*1000));

    sens = « right »;

    return false; // Empêche l’action du lien (l’encre # remonte en haut de la page)

    });

    Merci pour la remarque ;)

  12. JP dit :

    Super tutoriel, très bien fait et expliqué…

    Juste pour pinailler, j’aurais nommé le fichier SCRIPT.JS de manière plus significative, du genre DIAPORAMA_PARAMS.JS

  13. janguifett dit :

    Super ce tutoriel.

    Vraiment ce blog est très intéressant !

    Juste une petite chose :
    Le fichier .zip a télécharger est de la forme : jquery.diaporama.zip et winrar ne reconnaissait pas l’extension à cause du point entre jquery et diaporama…

  14. mb dit :

    Superbe de clarté et de simplicité: bravo.

    Etant novice, comment peut on mettre indifféremment des images verticales et horizontales et faire en sorte qu’elles soient centrées ?
    (j’arrive a les avoir toutes de la même hauteur, mais…)

    merci

  15. philippeW dit :

    bonjour Guillaume,
    je viens de découvrir votre tutoriel qui est vraiment bien. Mon seul soucis c’est, qu’une fois installé dans un tableau html, les flèches de navigations ne s’affichent pas. Elles restent néanmoins actives au survol de la souris.
    Avez-vous une solution ?
    En vous remerciant

  16. Guillaume dit :

    Bonjour Guillaume,

    C’est un très bon tutoriel, chaque ligne est clairement expliqué, un vrai plaisir à lire.

    Concernant le résultat final, et pour une raison que j’ignore, le fadeIn fadeOut fonctionne très bien sur Firefox, mais pas sur ma version de Chrome, si tu as une explication, je serais très intéressé de la connaître.
    J’espère avoir très prochainement le plaisir de lire d’autres tutoriels sur ton blog.

    À très bientôt,

    Guillaume

  17. vero dit :

    Bonjour,

    Merci pour le script. C’est exactement ce que je cherchais.
    Maintenant que ça fonctionne j’aimerais que les boutons du controler n’apparaissent qu’en survolant le diaporama.
    J’imagine que c’est possible mais comme je ne m’y connais pas en javascript… je préfère demander.

    Encore félicitation !

  18. Xavier dit :

    Super, juste ce dont j’avais besoin. Simple, clair et efficace.
    Merci

  19. Phil dit :

    Merci pour ce superbe tutoriel !

    Juste pour faire le perfectionniste, j’ai remarqué qu’aléatoirement le script engendre une erreur sur la console d’erreurs de mozilla :

     » Erreur d’analyse de la valeur pour « opacity ». Déclaration abandonnée.  »

    Rien de bien méchant cependant….

  20. orl dit :

    bravo, bravo, bravo
    j’ai pu utiliser ce tutoriel
    exactement ce que je cherchais depuis des lustres
    juste une petite question, (j’ai cherché et pas trouvé tout seul)
    comment faire démarrer le diaporama en mode « pause » par defaut, et laisser a l’utilisateur le choix de le démarrer ou de changer les photos a sa guise ..?
    l’inverse de ce qui ce passe dans ce script

    merci encore pour cette perle

  21. Guillaume dit :

    @orl: Pour démarrer le diaporama en mode pause par défaut, il faut commenter cette ligne:

    // setInterval(function(){nextElt(options)}, (options.delay*1000));

    en début de script, et changer la classe du bouton pour afficher le picto « pause ».

    Ensuite le comportement suivra. Tu dois pouvoir t’en sortir comme ça ;)

  22. Felicie dit :

    Bonjour, bravo, c’est très bien vulgarisé pour les novices
    En revanche, je souhaiterai remplacer les boutons de contrôle par du texte.
    Pouvez-vous m’aider ?
    Merci

  23. Guillaume dit :

    Pour remplacer les boutons par du texte, il suffit de modifier le fichier css et enlever les propriétés suivantes sur les boutons :
    - background
    - text-indent
    - display

    Et hop comme par magie, le texte apparait !

  24. webmasternic dit :

    Un grand merci pour cet excellent tutoriel très détaillé. Il m’a permis de réaliser un diaporama sur ma page d’accueil reprenant mes photographies publiées sur mes pages. L’atout de ce diaporama est de pouvoir ajouter un lien sur l’image mais également d’ajouter un descriptif de l’image – élément essentiel pour un meilleur référencement des images.

  25. soso dit :

    bonjour,
    merci pour ce tutoriel cepandant les boutons precedent pause et suivant s affiche tres bien sous firefox mais pas sous internet explorer. avez vous une solution a ce probleme??
    merci

  26. Gui dit :

    @ Soso : Effectivement, il y a un petit problème avec IE (6 & 7) dû à une mauvaise interprétation du style « inline-block + text-indent ». Je l’ai corrigé en ajoutant un espace « &nbsp; » dans le div class=’ btns’ et hop ça remarche sous IE !

    Je l’ai mis à jour dans la demo et le zip.

    Merci pour la remarque ;)

  27. Bat dit :

    Bonjour,

    La page d’accueil de mon site ( http://www.lp-jard.fr/spip ) contient actuellement un diaporama en Flash qui fonctionne correctement.

    Cependant, pour des raisons d’accessibilité, je voudrais utiliser le diaporama présenté ici mais je voulais savoir si il était possible de charger les images une par une dans la page ??

    Merci

  28. Vic dit :

    En un mot comme en cent : Excellent !

    Remarque : IE6 & 7 ne semblent toujours pas répercuter correctement la modif du 28/06.
    Ca marche pour ces navigateurs chez vous ?

  29. Gui dit :

    @ Vic Merci !

    Oui cela fonctionne chez moi sur IE 6 & 7, bien que vous me direz le png transparent n’est pas très zoli sur IE 6! Mais sur mon blog je me permets d’éliminer certaines contraintes :)

  30. prad dit :

    Bonjour Guillaume,

    Est-il possible de gérer le nombre de boucle du diaporama?
    Par exemple, ne faire réaliser qu’un seul « tour », au lieu de tourner ad libitum.

    Merci pour tout,
    françois

  31. Gui dit :

    @ Prad: Oui tu peux tout à fait envisager de rajouter un paramètre « boucles » dans le script par défaut à 0 (illimité) par exemple, et de vérifier dans les fonctions « next » et « prev » ce paramètre (est-il supérieur à 0 ?) et décrementer une autre variable en fonction et ne plus appeler la fonction next ou prev lorsque cette variable arrive 0. Le diaporama s’arrêtera alors.

    Il ne te reste plus qu’à essayer ;)

  32. alain dit :

    Bonjour,

    D’abord merci pour ce diaporama vraiment utile.
    Je reviens juste sur le démarrage de la page en mode pause.
    J’ai modifié le script comme signalé et changer la classe.
    Ca fonctionne mais en cliquant sur lecture le diaporama ne redémarre pas. Il faut passer par la flèche suivant pour qu’il se lance ce qui n’est pas pratique.
    Comment faire pour le relancer en cliquant simplement sur la fleche lecture quand il est sur pause par défaut ?
    Merci pour ta réponse.
    alain

  33. iki dit :

    Merci infiniment pour le temps passé à décortiquer ce script que du coup, ô miracle, j’ai compris ! :-)
    Diaporama impeccable, simple et pratique, que demander de plus ?

    Bravo et merci à Guillaume :-)

  34. Lau dit :

    Bonjour,
    Tout d’abord, un grand merci pour ce diaporama très facile à mettre en place et efficace… sauf qu’en effectuant des tests sur plusieurs postes, je m’aperçois que les boutons de controle ne s’affichent pas pour tous. Y a-til un moyen d’y remedier (j’ai mis un espace comme la modif du 28 juin mais rien…).
    Help !

  35. Lau dit :

    ReBonjour,

    Toujours un grand merci et bonne nouvelle, j’ai trouvé ! En fait, quand IE est en mode Affichage de compatibilité, les boutons de contrôle ne s’affichent pas…
    A bon entendeur !

Laisser une réponse