Une fois n’est pas coutume, voici un petit script jQuery.
NB : Stéphane soulève un problème d’accessibilité dans les commentaires, ne passez pas outre.
Il permet lors de l’activation d’une ancre de déplacer progressivement l’ascenseur de la page en fonction. J’aime personnellement beaucoup cet effet car je trouve qu’il rend plus compréhensible l’utilisation des ancres.
var scrolling = function(){
var speed = 1000;
jQuery('a[href^="#"]').bind('click',function(){
var id = jQuery(this).attr('href');
if(id == '#')
goTo('body');
else
goTo(id);
return(false);
});
function goTo(ancre){jQuery('html,body').animate({scrollTop:jQuery(ancre).offset().top},speed,'swing',function(){
if(ancre != 'body')
window.location.hash = ancre;
else
window.location.hash = '#';
jQuery(ancre).attr('tabindex','-1');
jQuery(ancre).focus();
jQuery(ancre).removeAttr('tabindex');
});
}
};
Point par point, cela donne :
var scrolling = function(){
Déclaration de la fonction, qui sera à déclencher au chargement de la page.
var speed = 1000;
On choisi une vitesse pour l’effet. Ce paramètre peut être modifié à loisir.
jQuery('a[href^="#"]').bind('click',function(){
On intercepte le click
sur les liens qui renvoient vers des ancres…
var id = jQuery(this).attr('href');
if(id == '#')
goTo('body');
else
goTo(id);
return(false);
Et on déclenche la fonction d’animation en fonction de la destination (haut de page ou ancre). On annule ensuite le comportement par défaut du lien.
function goTo(ancre){jQuery('html,body').animate({scrollTop:jQuery(ancre).offset().top},speed,'swing',function(){
L’astuce repose sur l’utilisation de la fonction animate
, qui pour le coup simplifie bien le code.
if(ancre != 'body')
window.location.hash = ancre;
else
window.location.hash = '#';
En callback
, on prend soin de changer le hash
dans la barre d’adresse pour ne pas différer du comportement normal.
jQuery(ancre).attr('tabindex','-1');
jQuery(ancre).focus();
jQuery(ancre).removeAttr('tabindex');
});
}
};
On place enfin un tabindex
négatif sur l’ancre, afin de pouvoir ensuite forcer le focus
dessus. Ainsi, logiquement, même les lecteurs d’écrans devraient s’y retrouver.
On termine enfin par un peu de ménage.
N’hésitez pas à critiquer le tout ! La démo est disponible ici.
39 commentaires ↓
Je trouve l’idée intéressante, tu as un exemple visible ?
On peut voir une tite démo ?
Je suis curieux notamment de savoir si ça n’empêche pas le navigateur d’enregistrer le clic et de permettre de revenir en arrière dans la page (comme je l’avais vu sur certains sites).
(Au passage, il manque un background-repeat:no-repeat; sur la liste MarkItUp).
Si je ne me trompe pas, c’est le principe d’un de mes plugins SPIP préférés, « Ancres douces » que l’on peut apprécier sur les blogs du Monde diplo : afficher un billet commenté, puis sur les ancres de la page qui permettent de sauter aux commentaires, puis d’un commentaire à l’autre, etc.
Comme toi, j’aime beaucoup cet effet, parce qu’il explicite les liens dans la page.
Il me semble qu’il existe un petit plugin « ScrollTo » qui ajoute cet effet de défilement doux en faisant un add-on de la fonction javascript de base « window.scrollTo ».
Voici l’exemple qui va bien rapidement codé.
Goulven : OVH a eu quelques soucis cette après-midi, c’est sans doute ça.
tetue : du coup, tu charges quelques kilos supplémentaires avec les plugins jQuery d’Ariel Flesler, non ? Ils permettent bien plus de choses mais pour le coup, je n’en avais pas besoin.
Shemu : c’est justement le plugin cité plus haut il me semble.
Bien.
Je sape le moral de tout le monde ?
Comme je le disais sur spip-contrib :
Et c’est le même problème ici… désolé, hein. Je n’ai pas de solution, mais il m’est impossible d’entériner ce genre de système tant que je n’aurai pas de solution à prposer.
Je ne comprend pas Stef, j’ai justement un comportement normal au niveau de l’historique moi.
Tu as testé avec un navigateur particulier ?
Je viens de le faire avec Firefox, Safari et Opera sous mac. Idem sous Firefox et IE PC.
Tu ne voudrais pas reproduire ton article sur jquery.info ?
@Vincent : tu as un Mac ou un Windows sous la main ?
Firefox/Win : je clique sur « bas », ça scrolle gentiment.
Je fais back et je reste comme un gros niais en bas de page… et je suis triste… 😉
Ok Stéphane, compris !
Le souci devrait pouvoir se corriger facilement en ajoutant une « ancre vide » au chargement de la page non ?
Je vais essayer ça.
Bon… ça ne marche pas. Je suis triste aussi tiens.
Voilà. Tu vois mieux mon problème, maintenant ? Pour l’instant, pour moi, c’est insoluble.
C’est problématique oui.
Néanmoins le confort apporté (notamment pour les utilisateurs néophytes) est certain. Et le cas d’utilisation que tu pointes du doigt est relativement peu fréquent.
J’avoue que je suis mitigé…
Tu conseilles de mettre à la poubelle dans tous les cas toi ?
Je cherchais justement un effet similaire sur des pages faisant déjà appel à la bibliothèque jquery. ce script est vraiment très bien 😉 Pour contourner le problème évoqué par Stéphane (ne pas casser l’historique de navigation), il suffit de remplacer return (false) par void(0)
On dirait bien que ça marche : merci Bruno !
Bravo Bruno ! Génial !
(je vais vite le redire sur spip-contrib)
Bonjour, etd’abord bravo, cet effet est exactement ce que je cherchais. A un bémol près, que je vous soumets : avant que le script ne fasse « glisser » la page, l’ancre html a le temps de fonctionner. Du coup, avant l’effet de glissement, on a le temps de voir l’endroit cible pendant une fraction de seconde. Pour détailler ce qui se passe, au moment du clic, la page saute instantanément à la position de l’ancre, puis revient instantanément au point de départ pour retourner (en glissant harmonieusement, cette fois) vers la position de l’ancre. Lorsque la page ne contient que du texte, l’oeil ne s’en rend pas compte, mais lorsqu’il y a des images en décor de page, c’est flagrant, on a le sentiment d’un bug. Les programmeurs émérites que vous êtes auraient-ils une solution (je ne suis qu’un modeste graphiste ignorant de javascript, avec seulement quelques bases en AS3) ?
Bonjour,
Je me pose exactement la même question! Ce code fonctionne à merveille mais cet effet subliminal est dérangeant. Si une solution existe elle serait la bienvenue !
Merci ! Exactement ce que je cherchais. J’ignore pourquoi, le bout de code précédent que j’utilisais pour faire la même chose sur mon blog a cessé de fonctionner…
Merci encore.
Serait il possible d’éviter d’avoir une mise en valeur (rectangle bleu sur chrome, rectangle en pointillé sur firefox) de l’ancre visée ?? c’est assez génant, et je ne vois pas d’ou cela vient. Merci
C’est un point important qui permet de rendre la technique accessible, ce qui était mon postulat de départ.
(La réponse m’est destinée ??)
Oui, oui.
Je n’ai pas compris alors … tu veux dire que l’effet que j’aimerais éviter est justement voulu ? (Si oui, comment je fais pour l’enlever ?)
Moi, je le veux… donc je ne l’enlève pas. 😉
Et c’est pour le coup une bonne pratique donc je te conseille de faire de même. Mais tu peux chercher du côté de CSS sinon, avec focus…
?? une bonne pratique, peut être, mais ce rectangle bleu est moche … enfin merci.
Terrible merci… 😉
Bonjour,
merci pour le tuyau !
Je suis en pleine refonte de site passant du flash au css, et ce tuto m’est d’une trés grande utilité.
Muchas gracias !
Pour le cadre pointillé, enlève : jQuery(ancre).focus();
Une petite question de débutant …
Cette fonction qui est plus qu’intéressante mais cependant ne fonctionne que pour les liens qui ressemblent à :
<a href="#ancre"></a>
mais comment faire pour les liens qui ressemblent à:
<a href="ma_page.php#ancre"></a> ?
J’ai essayé et ça ne fonctionne pas. Alors je me suis dis que ca proviendrai surement de cette ligne :
jQuery('a[href^="#"]').bind('click',function(){
Mais je ne parviens pas à la modifier, je suis un peu nul en expressions régulières.
Pouvez vous éclairer ma lanterne ?
Merci !
Pour Zavo, c’est le remplacement du return (false) par void(0) qui pose ce problème. ++ O
Bonjour ce script m’arrange bien mais me pose un probleme qui est que je suis oblige de cliquer deux fois sur le lien pour obtenir l’effet scroll! Quelqu’un peut m’aider?
Je reprends la demande de Didier toujours en attente d’une réponse, car je suis moi même confronté à un soucis. Le script intercepte le clic sur le lien. Mais là je souhaiterais lancer l’animation une fois le chargement de la page terminé… donc avec ce type d’url: http://monsite.fr#ancre
Merci
Bonjour,
J’ai réalisé un « menu fixe » d’une hauteur 80 pixels sur ma page html. J’ai rajouté des liens internes (Ancre1) et des Ancres internes ()sur cette page pour accéder directement à l’information.
Le problème, c’est que le positionnement de la page se fait toujours sous le « menu fixe », je suis ensuite obligé de déplacer l’ascenseur verticalement pour arriver au bon endroit.
Comment rajouter un décalage (Offset) de 80 pixels quand je clique sur les liens internes?
Voici le lien avec mon exemple: http://www.asd-multimedia.com/test/ Merci pour votre aide.
Merci pour ce Script ainsi qu’à tous ceux qui ont permis à résoudre certains problème…!
Mercip our ce script, mais même problème que Piin-pin, personne n’a la solution à ce problème? Merci
[…] […]
Je suis très intéressé par cette fonction, mais le cadre bleu hideux qui apparait sur les ancres cibles gâche tout. Franchement, c’est juste pas possible pour 99% des designs web. En plus ça n’apporte rien à part polluer la mise en page. Je suis très embêté car je ne peux pas utiliser ce script si je ne peut pas enlever ce rectangle bleu. Je suis graphiste, pas développeur, et mes notions en code se limitent presque au copier coller.
Comment supprimer ce défaut simplement pour ne conserver que l’effet d’ascenseur progressif ?
Quelqu’un a t-il trouvé un autre tutoriel simple ? Merci.
bonjour
effet tres interessant… j’essaie de comprendre mais evidemment ça ne marche pas…je voudrais l’appliquer au rafraichissement et positionnement d’une liste apres saisie dans un pop-up externe cest a dire avec generation dynamique de l’ancre sur une ligne precise
je ne comprends pas tout le code mais en fait il faudrait declencher sur l’evenement onload de la page (sans clic) pour que le positionnement soit automatique au re-chargement surement possible mais je ne suis pas expert en jquery
merci d’avance si vous pouvez m’eclairer
Laisser un commentaire