Après une demande reçue par e-mail, je me suis dit que la fonctionnalité serait peut-être utile à d’autres que moi.
Lors de la rédaction de ce tutoriel : jQuery – Effet Smooth Scroll (défilement fluide), la complexité du contenu m’a fait retirer une extension intéressante à la dernière fonction/plugin proposée.

Il s’agit d’une mise à jour

  1. [Mise à jour] jQuery – Effet smoothscroll au chargement de la page

Avant propos

C’est toujours dans une optique de simplicité que j’essaye de présenter mes tutoriels. Il est clair qu’il y a des points parfois difficiles à faire comprendre au plus grand nombre, c’est aussi pour cela que je vous invite toujours à me signaler toute incompréhension sur un tutoriel que vous liriez.

C’est aussi pour cela qu’il m’arrive d’avoir des tutoriels complexes, et de les épurer en retirant des éléments que je juge inutiles – au moins dans un premier temps.

Mise à jour

Le tutoriel « jQuery – Effet Smooth Scroll (défilement fluide) » a été mis à jour aujourd’hui même afin de faire bénéficier à sa troisième partie d’une meilleure prise en charge des URL absolues fournies d’un hash (exemple : http://creativejuiz.fr/blog#kiwi).

Ce tutoriel utilise l’objet $.browser retiré depuis la version 1.9 de jQuery. Pour plus d’information : Note de version 1.9 de jQuery.
Vous pouvez cependant utiliser le script complémentaire présent sur Chez-Syl.fr. Merci à Xeroc pour l’info.

Pour les utilisateurs de jQuery 1.9 et supérieures, il faudra penser à remplacer dans le code ci-dessous :
Live() : $(this).live('click', function() par: $(this).on('click', function()

Effet de défilement au chargement de la page

Pour effectuer un effet de défilement, voilà comment expliciter la chose en français :
« On cherche à obtenir le même résultat qu’au clic sur l’ancre porteuse du lien vers la cible présente dans la barre d’adresse. »

Voir la démonstration

Il nous faut prendre la phrase à l’envers et la transformer en jQuery.
Donc en plusieurs étapes il nous faut :

  1. Récupérer le contenu de la barre d’adresse
  2. Récupérer uniquement le hash
  3. Chercher dans notre document quel élément pour l’attribut href="#hash"
  4. Simuler un clic sur cette élément pour déclencher le défilement

Ok, voici un code qui fait ça :

function trigger_click_for_slide() {
      var the_hash = document.location.hash;
      if(the_hash)
          $('a[href~="'+the_hash+'"]').trigger('click');
}
trigger_click_for_slide();

La ligne 2 nous permet de stocker directement le hash (fin de l’URL) dans une variable.
La ligne 3 permet de vérifier l’existence d’un hash en bout d’URL.
La ligne 4, primordiale, permet de simuler (trigger) l’évènement click sur l’élément porteur d’un href ciblant le hash trouvé dans l’URL.

Pourquoi imiter le clic sur un lien plutôt que d’effectuer directement une animation ?
Pour éviter de réécrire une portion du code, et aussi pour limiter les animations vers les ancres prévues par notre système de navigation.

Ce morceau de code peut être placé après la création d’une des mini fonctions vues dans l’article jQuery – Effet Smooth Scroll (défilement fluide).

Note : Petite astuce donnée par notre ami Brice pour optimiser cette partie du code. Merci à lui 😉

Écriture du hash dans l’URL

Ninja portant des hastags-shurikenC’est bien sympa de proposer un défilement au chargement, mais puisque le hash ne s’écrit plus dans la barre d’adresse, comment allez vous faire pour partager une URL fournie d’un hash ?

Il faut le réécrire… oui d’accord, mais comment ?
Si on enlève le return false; en fin de fonction, le défilement va sauter, puis défiler de manière fluide, ou inversement.

Il faut donc le faire une fois l’animation terminée !
Je vous l’avez dit dans le précédent tutoriel à ce sujet, la fonction animate() permet l’accueil d’une fonction de callback.

Nous allons donc créer une fonction au sein du mini plugin vu dans l’ancien article, qui va nous permettre de réécrire le hash dans la barre d’adresse.
La voici :

function write_hash(the_hash) {
	    document.location.hash = the_hash;
}

Ensuite il faut faire appel à cette fonction dans notre plugin dans la partie qui gère l’animation :

$('html, body').animate({  
        scrollTop:$(the_element).offset().top  
}, speed, function() {
        write_hash(the_hash);
}); 

Au final, nous avons un code complet qui nous donne :

(function($) {  
	$.fn.juizScrollTo = function( speed ) { 
		if ( !speed ) var speed = 'slow';  
 			
		// coeur du plugin
		return this.each( function() {  
			$(this).live('click', function() {  
				var goscroll = false;  
				var the_hash = $(this).attr("href");  
				var regex = new RegExp("(.*)\#(.*)","gi");
				var the_element = '';
 
				if ( the_hash.match("\#(.+)") ) {  
					the_hash = the_hash.replace(regex,"$2");  
					if($("#"+the_hash).length>0) {  
						the_element = "#" + the_hash;  
						goscroll = true;  
					}  
					else if ( $("a[name=" + the_hash + "]").length>0 ) {  
						the_element = "a[name=" + the_hash + "]";  
						goscroll = true;  
					}  
					if ( goscroll ) {  
						$('html,body').animate( {  
							scrollTop: $(the_element).offset().top  
						}, speed, function() {
							tab_n_focus(the_hash)
							write_hash(the_hash);
						});  
						return false;  
					}  
				}  
			});  
		});
 			
		// fonctions
 			
		// écriture du hash
		function write_hash( the_hash ) {
			document.location.hash =  the_hash;
		}
 			
		// accessibilité au clavier
		function tab_n_focus( the_hash ) {  
			$(the_hash).attr('tabindex','0').focus().removeAttr('tabindex');  
		}
 
	};  
 		
	// appel de la fonction sur toutes les ancres !
	$('a').juizScrollTo('slow');
 		
	// fonction de slide au chargement
	function trigger_click_for_slide() {
		var the_hash = document.location.hash;
		if ( the_hash )
			$('a[href~="'+the_hash+'"]').trigger('click');
	}
	trigger_click_for_slide();
 
})(jQuery)

Avec les versions de jQuery supérieure à 1.7.0, favorisez l’utilisation de on() en lieu et place de live(). Regardez bien la documentation pour effectuer les petits changements adéquats.

Voilà… je crois que nous avons un code plutôt complet pour ce type d’effet :

  • Gestion des URLs relatives et absolutes
  • Navigation au clavier
  • Réécriture du hash dans l’URL (pratique pour le partage d’une info précise)
  • Effet smoothscroll au chargement de la page (si on cible quelque chose sur la page via l’URL)

Note : pour ceux qui exécuteraient le JavaScript en tout début de document, n’oublier pas d’utiliser $(document).ready(function(){ /*contenu de la fonction*/ }); pour n’exécuter le code qu’une fois le document HTML chargé.

N’hésitez pas à laisser un commentaire pour toute remarque sur ce code, problème rencontré, etc…

Merci pour votre lecture et à la prochaine.