Vous êtes ici : Accueil du blogjQuery, Responsive » Comment initialiser (ou détruire) un slider en fonction d’un breakpoint ?

Comment initialiser (ou détruire) un slider en fonction d’un breakpoint ?

Dans cet article nous allons mettre en pratique la technique vue précédemment pour tester un breakpoint en javascript. L’objectif étant ici de remplacer à la volée une liste d’images sur desktop par un slider sur mobile, au resize sans rechargement de page.

  1. [#] La structure de base
  2. [#] Le code javascript
  3. [#] La mise en forme CSS

Pour l’exemple nous utiliserons le plugin Owl Carousel, mais la technique fonctionne avec n’importe quel autre slider du moment que celui-ci intègre une méthode de destruction.

Voir la démo

Attention, certaines versions du plugin ne gèrent pas correctement la destruction. Si vous remarquez qu’il traine toujours des conteneurs et des classes propriétaires dans votre code, essayez avec autre version (ça fonctionne avec la 2.1.6, dernière release au moment de la publication).

La structure de base

On part sur du relativement classique, mettez en place le markup de votre galerie comme vous avez l’habitude de le faire :

<div class="myGallery">
	<div class="item"><img src="img/photo-1.jpg" alt=""/></div>
	<div class="item"><img src="img/photo-2.jpg" alt=""/></div>
	<div class="item"><img src="img/photo-3.jpg" alt=""/></div>
	<div class="item"><img src="img/photo-4.jpg" alt=""/></div>
</div>

La seule contrainte étant d’anticiper une éventuelle structure spécifique au slider que vous utiliserez. Par exemple le FlexSlider impose que vous ayez un conteneur supplémentaire autour de la galerie.

Le code javascript

Commencez par mettre en place les éléments de l’article précédent permettant de tester le breakpoint courant. Il faudra récupérer le code de la méthode avancée, puisqu’il est important de pouvoir faire la vérification « en live ». Cela permettra notamment de gérer le cas où l’utilisateur change d’orientation sur un device mobile.

Et voici le code javascript à ajouter dans votre common.js. On en parle juste après.

// ---------------------------------------------------- //
// SLIDER GALLERY
// ---------------------------------------------------- //
var sliderGallery = function() {

	/*** Vars ***/
	var gallery = '.myGallery',
		slider = false;

	/*** Init ***/
	var init = function() {

		manage(); // On load (1*)

		$(window).on('resize', function(){ // On resize (2*)
			waitForFinalEvent(function(){
				manage();
			}, 200, "sliderGallery");
		});

	};

	/*** Manage slider ***/
	var manage = function() {

		var isMobile = breakpoints.is('bp_mobile'); // Test breakpoint

		if( isMobile && !slider ) { // If mobile and slider not built yet = build
			build();
		}
		else if( !isMobile && slider ) { // Not mobile but slider built = destroy
			destroy();
		}

	};

	/*** Build slider ***/
	var build = function() {
		slider = $(gallery).addClass('owl-carousel'); // Add owl slider class (3*)
		slider.owlCarousel({ // Initialize slider
			items:1,
			slideBy:1,
			nav:true,
			loop:true,
			dots:false
		});
	};

	/*** Destroy slider ***/
	var destroy = function() {
		slider.trigger('destroy.owl.carousel'); // Trigger destroy event (4*)
		slider = false; // Reinit slider variable
		$(gallery).removeClass('owl-carousel'); // Remove owl slider class (3*)
	};	

	/*** Public methods***/
	return {
		init: init
	};

}();

// ---------------------------------------------------- //
// PREVENT MULTIPLE CALLS
// ---------------------------------------------------- //
var waitForFinalEvent = (function () {
	var timers = {};
	return function (callback, ms, uniqueId) {
		if (!uniqueId) {
			uniqueId = "Don't call this twice without a uniqueId";
		}
		if (timers[uniqueId]) {
			clearTimeout (timers[uniqueId]);
		}
		timers[uniqueId] = setTimeout(callback, ms);
	};
})();

Il ne reste plus qu’à initialiser le script :

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="js/owl.carousel.min.js"></script>
<script src="js/common.js"></script>
<script>
	$(document).ready(function() {

		// Init slider gallery
		sliderGallery.init();
	});
</script>

Il se passe deux choses lors l’initialisation du script :

  • On vérifie si le slider doit être immédiatement construit, au chargement de la page. (1*)
  • On attache un évènement resize à la fenêtre du navigateur pour appeler le script lors du redimensionnement. (2*)

La plupart des navigateurs (tous sauf Opéra) déclenchent l’évènement resize continuellement pendant le process de redimensionnement. Les calculs effectués lors de la construction d’un slider étant relativement complexes, il est important de les effectuer dans de bonnes conditions afin de limiter les ressources machines utilisées (et accessoirement les bugs :). La méthode waitForFinalEvent() va permettre d’attendre la fin du processus de redimensionnement pour passer à l’étape suivante.

Certains sliders nécessitent des classes propriétaires pour fonctionner correctement, c’est le cas du Owl Carousel. Il faudra donc les gérer au moment de la construction / destruction (3*). N’oubliez pas d’appeler la feuille de styles du plugin dans votre <head>.

Comme pour l’initialisation et les options, la méthode de destruction varie d’un slider à l’autre. Référez-vous à la documentation de votre plugin pour trouver la bonne technique. (4*)

La mise en forme CSS

On se retrouve dans un cas de figure où la structure doit accueillir deux mises en forme différentes : avec et sans slider. Comment la styler efficacement en évitant la surcharge ? Je vous propose deux astuces, en fonction de la compatibilité navigateurs recherchée :

  • Si pas d’IE8, la solution la plus simple me semble d’utiliser le sélecteur :not() associé à une classe propriétaire (3*) du slider :

    /*** No slider ***/
    .myGallery:not(.owl-carousel) { ... }
    .myGallery:not(.owl-carousel) .item { ... }
    
    /*** Slider ***/
    .myGallery.owl-carousel { ... }
    .myGallery.owl-carousel .item { ... }
  • Sinon, rien ne vous empêche de gérer vos propres classes :

    $(gallery).removeClass('css-noslider').addClass('css-slider'); // @build
    $(gallery).removeClass('css-slider').addClass('css-noslider'); // @destroy
    /*** No slider ***/
    .myGallery.css-noslider { ... }
    .myGallery.css-noslider .item { ... }
    
    /*** Slider ***/
    .myGallery.css-slider { ... }
    .myGallery.css-slider .item { ... }

    Je vous remets la démo, n’hésitez pas à venir échanger autour de cet article via les commentaires ;)

    Voir la démo

Laisser un commentaire

Balises HTML autorisées dans la rédaction du message :
<strong> <a> <code> <q>

Les champs marqués d'une étoile sont obligatoires.

Current month ye@r day *