[Mise à jour] jQuery – Effet smoothscroll au chargement de la page
publié le 21 novembre 2011 à 8 h 47 min
Lu 2 902 fois.
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.
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).
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. »
Il nous faut prendre la phrase à l’envers et la transformer en jQuery.
Donc en plusieurs étapes il nous faut :
- Récupérer le contenu de la barre d’adresse
- Récupérer uniquement le hash
- Chercher dans notre document quel élément pour l’attribut href="#hash"
- 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).
Écriture du hash dans l’URL
C’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 :
$(container).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).click( function() {
var goscroll = false;
var the_hash = $(this).attr("href");
var regex = new RegExp("(.*)\#(.*)","gi");
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 ) {
var container = 'html';
if ( $.browser.webkit ) container = 'body';
$(container).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)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)
N’hésitez pas à laisser un commentaire pour toute remarque sur ce code, problème rencontré, etc…
Merci pour votre lecture et à la prochaine.



Ça l air plutôt sympa comme effet et ton tuto semble très explicite. Je relirais ton tuto à tete reposé. Àpres 4h de sommeil avec le ptit monstre, les choses se brouilles un peu quand meme …
Ah ah ! Tu nages dans le brouillard ! :p
Merci pour le coup d’œil à venir, je suis ouvert à toute remarque sur le fond comme sur la forme
Bon courage.
Pourquoi ne pas se servir de la propriété location.hash plutôt que des expressions régulières ?
http://www.w3schools.com/jsref/prop_loc_hash.asp
@Birken : merci pour cette remarque.
J’avais le souvenir, peut-être à tort, que IE7 avait un problème d’interprétation de location.hash. Je n’ai donc pas pris la peine de tester, la solution regex me semblait convenir ici.
Je ferai un essai dans le week-end, car ça pourrait davantage simplifier le code
Merci.
Apparement sans problèmes, même avec IE6 :
http://stackoverflow.com/questions/1263509/potential-problems-setting-window-location-hash
Merci pour cette information Birken.
Je corrige mon code en conséquence
Joli tuto, j’avais fait un ptit plugin sur le sujet. Je crois qu’il a un petit souci de compatibilité sur un IE (faudrait que je me repenche dessus).
http://project.cahnory.fr/jquery.scrollIn/
Hey sympa
Merci pour le partage.
Merci pour ce tuto.
Je l’ai adapté pour que le container soit paramétrable pour que l’effet smooth fonctionne aussi dans un div. Du coup, je peux gérer plusieurs scrollbars.
Pour mon cas, j’ai changé le scrollTop en scrollLeft.
En conséquence, mon scrollLeft devient :
scrollLeft: $(the_element).offset().left – $(container).children().offset().left
Je n’ai pas lu le tuto en entier mais si je ne me trompe pas, le résultat final est le même que propose le plugin jQuery « ScrollTo » ?
Bonjour,
Je n’ai pas lu tout ton commentaire mais je pense que tu n’as pas lu tout l’article.
Merci
Après lecture complète :
Ce n’engage que moi mais le plugin jQuery ScrollTo avec éventuellement le plugin jQuery Ascensor, nous permet d’obtenir un résultat plus « propre » que l’exemple de démonstration.
http://www.kirkas.ch/ascensor/
Aucun rapport avec ce tutoriel, mais l’ouverture dans une nouvelle fenêtre pour l’exemple de démonstration permettrait une meilleure navigation pour ne pas dire « experience utilisateur ».
Je te remercie pour ta lecture et ton avis, mais je t’avoue que certaines choses m’échappent :
Concernant ta dernière remarque, on voit là un défaut de maturité de ta réflexion. En quoi imposer un mode de navigation permet de proposer une meilleure expérience utilisateur ? Si l’utilisateur veut ouvrir la démonstration dans un nouvel onglet, il le fait par lui même.
Comment fait l’utilisateur pour ouvrir le lien dans le même onglet si je le force à faire autrement ?
Je suis ouvert à toute explication sur le terme trop vague que tu énonces : « propre ».
Merci et bonne soirée.
- Pourquoi comparer des plugins à un tutoriel ?
Ce n’est pas vraiment le tutoriel en lui même que je compare mais le résultat final (visuel).
- Pourquoi comparer deux outils qui n’ont pas la même vocation ?
Selon le niveau de la personne, elle peut être plus ou moins effrayée par toutes ces lignes de codes et ne cherchera pas à décrypter. C’est pourquoi, j’ai « soumis » deux plugins. Après je suis entièrement d’accord, celui qui souhaite vraiment mettre les mains dans le code, l’améliorer à sa sauce ou comprendre comment ça marche, ce tutoriel est juste parfait.
- Pourquoi charger 4 fichiers JS … pour un effet si simple quand deux suffisent dans le cadre de l’animation que je propose ?
Si l’effet final est exactement celui que propose ton tutoriel, il est clair qu’il vaut mieux utiliser 1 seul fichier JS (ton code). ScrollTo et Elevator proposent pas mal d’options super intéressantes et que l’on peut paramétrer très facilement. Sur un gros projet, bien sur ce n’est pas le bienvenu.
- d’ailleurs si je veux partager uniquement ton portfolio à un ami, je ne peux pas…
Mon but n’est pas que l’on partage uniquement une section du site mais le site entier.
- Chez moi si JS est désactivé, mon système d’ancre fonctionne toujours.
Chez moi aussi
. J’ai juste mis un « return false; » pour qu’il n’y ait uniquement le partage de l’URL sans ancre.
Donc en clair, selon l’objectif et le type du projet de chacun, il peut être bon de connaitre ton code ou bien ces deux plugins (ScrollTo marche très bien sans Elevator, mais pas l’inverse).
Bonne soirée.
Alors merci pour cette présentation, même si elle était déjà faite dans la première partie du tutoriel :
http://www.creativejuiz.fr/blog/tutoriels/jquery-effet-smooth-scroll-defilement-fluide
Au moins elle sera également lisible sur cette page.
J’essaye généralement de ne pas être trop centré sur mes propres codes et présenter des alternatives à mes lecteurs.
Concernant le problème de JS désactivé, je parlais de la page de démonstration de Ascensor. J’avoue ne pas avoir testé chez toi.
Merci pour ton commentaire.
Bonne continuation.
PS: tu as une erreur de logique sur un de tes cercles en canvas sur ton portfolio, relis bien les pourcentages.