Vous êtes ici : Accueil du blogjQuery, Responsive » Du JS spécifique aux devices grâce aux breakpoints CSS

Du JS spécifique aux devices grâce aux breakpoints CSS

Il existe différentes façons de détecter un appareil mobile afin de lui appliquer du code javascript spécifique.
La détection peut se faire :

  • Grâce à l’agent utilisateur (technique du « User Agent Sniffing », proposée par exemple sur Detect Mobile Browsers). L’inconvénient de cette solution est qu’elle nécessite une mise à jour du script si un nouvel appareil venait à sortir.
  • En testant la largeur de l’écran avec javascript. Et là il faudra être sûr de ce que l’on cherche : largeur de l’écran ou de la fenêtre ? scrollbar comprise ou non ? jQuery ou pur JS ? #1 / #2

Cette dernière technique pose également le problème de la maintenance des valeurs relatives au responsive qui devra se faire conjointement dans le CSS : @media only screen and (max-width:767px)
et le JS : if( window.innerWidth < 767 )

Si l’objectif est simplement d’appliquer du code JS spécifique à un breakpoint, alors la méthode suivante devrait vous intéresser.

  1. [#] Méthode simplifiée
  2. [#] Méthode avancée

Méthode simplifiée

  • En bas de page avant </body>, on « liste » des éléments vides qui correspondent à nos breakpoints :

    <span id="bp_mobile" class="bp_checking"></span>
    <span id="bp_tablet" class="bp_checking"></span>
    <span id="bp_desktop" class="bp_checking"></span>
    
  • Dans le .css, on les masque par défaut et on les affiche via les media queries correspondantes :

    .bp_checking { display:none; }
    
    @media only screen and (max-width:767px) {
    	#bp_mobile { display:block; }
    }
    
    @media only screen and (min-width:768px) and (max-width:1279px) {
    	#bp_tablet { display:block; }
    }
    
    @media only screen and (min-width:1280px) {
    	#bp_desktop { display:block; }
    }
    
  • Dans le .js qui regroupe nos fonctions (pour l’exemple common.js), on ajoute la méthode qui teste la visibilité des éléments :

    var isVisible = function(element) {
    	return $(element).is(':visible');
    };
  • Et on l’exploite dans notre page (dans le <head> ou en bas de page avant </body>) :

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
    <script src="js/common.js"></script>
    <script>
    	$(document).ready(function() {
    		var isMobile  = isVisible('#bp_mobile'),
    		    isTablet  = isVisible('#bp_tablet'),
    		    isDesktop = isVisible('#bp_desktop');
    
    		if( isMobile ) {
    			// Do complicated JS stuff on mobile
    		}
    	});
    </script>

Et voilà ! Un premier jet qui va nous permettre de poser les bases de la technique. Celle-ci pourra s’employer sans problème sur des petits projets contenant peu de breakpoints et de JS associé.

Méthode avancée

Pour des projets un peu plus exigeants, il peut être intéressant de mettre en place certains automatismes. Comme par exemple la récupération des breakpoints et leur stockage dans un tableau (afin d’éviter les sollicitations multiples du DOM) et leur mise à jour lors du resize.

On reprend notre common.js afin de l’agrémenter de quelques lignes de code supplémentaires :

// ---------------------------------------------------- //
// VISIBILITY CHECKING
// ---------------------------------------------------- //
var isVisible = function(element) {
	return $(element).is(':visible');
};

// ---------------------------------------------------- //
// BREAKPOINTS MANAGE
// ---------------------------------------------------- //
var breakpoints = function () {

	/*** Vars ***/
	var breakpoints = {},
		breakpoint_selector,
		breakpoint_isVisible;

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

		$('.bp_checking').each(function() { // First pass, loop on DOM
			manage( $(this).attr('id') );
		});

		$(window).on('resize', function(){ // On resize, loop on array
			$.each(breakpoints, function(breakpoint_id) {
				manage(breakpoint_id);
			});
		});
	};

	/*** Breakpoint testing ***/
	var is = function(breakpoint) {
		return breakpoints[breakpoint];
	};

	/*** Manage array ***/
	var manage = function(breakpoint_id) {
		breakpoint_selector = '#' + breakpoint_id;
		breakpoint_isVisible = isVisible(breakpoint_selector);
		breakpoints[breakpoint_id] = breakpoint_isVisible;
	};

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

}();

// Init
breakpoints.init();

Il vous suffira ensuite d’appeler la méthode publique is() pour réaliser vos tests :

if( breakpoints.is('bp_mobile') ) { /* Mobile-specific javascript */ }

On finit avec une petite démo pour mettre tout ça en application :

Voir la démo

Vous pouvez également jeter un coup d’oeil à l’article suivant, qui exploite cette technique pour initialiser / détruire un slider en fonction d’un breakpoint.


Quelques recherches effectuées autour de la performance :

  • id sur les éléments plutôt qu’une class ? #why
  • .is(':visible') plutôt que .filter(':visible') ou $(':visible') ? #why

Si vous voulez en savoir plus sur le design pattern utilisé pour construire la fonction :

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 *