Décalage de l'affichage des ancres et défilement (javascript)

3 participants

Voir le sujet précédent Voir le sujet suivant Aller en bas

Résolu Décalage de l'affichage des ancres et défilement (javascript)

Message par MlleAlys Ven 13 Mar 2015 - 15:17

Détails techniques


Version du forum : phpBB2
Poste occupé : Administrateur
Navigateur(s) concerné(s) : Google Chrome
Personnes concernées par le problème : Tous les utilisateurs
Lien du forum : http://forum-test-phpbb2.forumactif.org/

Description du problème

Bonjour !
Je reviens avec un nouveau petit souci de javascript, pour changer ! x3

J'ai trouvé un code javascript sur ce site permettant normalement de décaler l'affichage des ancres pour un confort de lecture et de faire défiler la page jusqu'à cette ancre plutôt que de l'afficher abruptement... Et comme j'ai trouvé ça très sympa, j'ai naïvement essayé de copier/coller le code dans un nouveau javascript dans les modules... sauf que ça ne fonctionne pas ! o/ Et je ne sais absolument pas ce qu'il faut modifier pour que ça fonctionne ? ^^"


Le code :
Code:
// Pour tous les liens commençant par #.
   $("a[href^='#']").click(function (e) {
      var
         yPos,
         yInitPos,
         target = ($($(this).attr("href") + ":first"));
         
      // On annule le comportement initial au cas ou la base soit différente de la page courante.
      e.preventDefault();
      
      yInitPos = $(window).scrollTop();
      
      // On ajoute le hash dans l'url.
      window.location.hash = $(this).attr("href");
      
      // Comme il est possible que l'ajout du hash perturbe le défilement, on va forcer le scrollTop à son endroit inital.
      $(window).scrollTop(yInitPos);
      
      // On cible manuellement l'ancre pour en extraire sa position.
      // Si c'est un ID on l'obtient.
      target = ($($(this).attr("href") + ":first"));
 
      // Sinon on cherche l'ancre dans le name d'un a.
      if (target.length == 0) {
         target = ($("a[name=" + $(this).attr("href").replace(/#/gi,"") + "]:first"))
      }
      
      // Si on a trouvé un name ou un id, on défile.
      if (target.length == 1) {
         yPos = target.offset().top; // Position de l'ancre.
      
         // On anime le défilement jusqu'à l'ancre.
         $('html,body').animate({ scrollTop: yPos - 40 }, 1000); // On décale de 40 pixels l'affichage pour ne pas coller le bord haut de l'affichage du navigateur et on défile en 1 seconde jusqu'à l'ancre.
      }
   });

Je l'ai laissé tel quel sur mon forum test, en mettant des liens vers la chatbox sur la page d'accueil pour pouvoir le tester...



Merci beaucoup d'avance pour votre aide !! =3


Dernière édition par MlleAlys le Sam 14 Mar 2015 - 14:54, édité 1 fois
MlleAlys

MlleAlys
Membre actif

Messages : 5767
Inscrit(e) le : 12/09/2012

MlleAlys a été remercié(e) par l'auteur de ce sujet.

Résolu Re: Décalage de l'affichage des ancres et défilement (javascript)

Message par oxymore Ven 13 Mar 2015 - 16:34

Bonjour

Vous avez bien mis
Code:
$(function() {
   
Votre code...

   });

Essayez aussi une autre ID
comme
Code:
 <a href="#page-footer">Le lien</a>
oxymore

oxymore
***

Messages : 141
Inscrit(e) le : 09/11/2008

http://www.google.fr
oxymore a été remercié(e) par l'auteur de ce sujet.

Résolu Re: Décalage de l'affichage des ancres et défilement (javascript)

Message par MlleAlys Ven 13 Mar 2015 - 16:42

AH ! Le function avant, je ne l'avais pas remis effectivement, merci !!! ><"

Le défilement et le décalage fonctionnent bien pour les ancres de type href="#id" , mais pas pour les liens vers une autre page de type href="/blabla#id" , y aurait il moyen qu'au moins le décalage fonctionne dans ces cas là ? =s
MlleAlys

MlleAlys
Membre actif

Messages : 5767
Inscrit(e) le : 12/09/2012

MlleAlys a été remercié(e) par l'auteur de ce sujet.

Résolu Re: Décalage de l'affichage des ancres et défilement (javascript)

Message par Self Ven 13 Mar 2015 - 19:45

Bonsoir MlleAlys Smile !

Tu peux essayer avec le code suivant Wink :
Code:
jQuery(function($){
   var a = sessionStorage.getItem('anchor'), yPos, yInitPos, target;

   function scrolling(href){

      yInitPos = $(window).scrollTop();
                   
      // On ajoute le hash dans l'url.
      window.location.hash = href;
                   
      // Comme il est possible que l'ajout du hash perturbe le défilement, on va forcer le scrollTop à son endroit inital.
      $(window).scrollTop(yInitPos);
                   
      // On cible manuellement l'ancre pour en extraire sa position.
      // Si c'est un ID on l'obtient.
      target = ($(href + ":first"));
               
      // Sinon on cherche l'ancre dans le name d'un a.
      if (target.length == 0) {
         target = ($("a[name=" + href.replace(/#/gi,"") + "]:first"))
      }
                   
      // Si on a trouvé un name ou un id, on défile.
      if (target.length == 1) {
         yPos = target.offset().top; // Position de l'ancre.
                   
         // On anime le défilement jusqu'à l'ancre.
         $('html,body').animate({ scrollTop: yPos - 40 }, 1000); // On décale de 40 pixels l'affichage pour ne pas coller le bord haut de l'affichage du navigateur et on défile en 1 seconde jusqu'à l'ancre.
      }
   }

   if(a){ var href = a; scrolling(a); sessionStorage.removeItem('anchor'); }
   // Pour tous les liens commençant par #.
   $("a").click(function (e) {

      var href = $(this).attr('href'), t = new RegExp('#.*'), anchor = new RegExp('^#.*');
      if(href.match(anchor)){ e.preventDefault(); scrolling(href); }else if(href.match(t)){
         e.preventDefault();
         sessionStorage.setItem('anchor', href.match(t));
         location.href = href.replace(/#.*/, '');
      }
   });
});
Self

Self
Membre actif

Masculin
Messages : 3853
Inscrit(e) le : 13/06/2013

https://selfback.forumactif.com/
Self a été remercié(e) par l'auteur de ce sujet.

Résolu Re: Décalage de l'affichage des ancres et défilement (javascript)

Message par MlleAlys Ven 13 Mar 2015 - 20:04

Bonsoir SeLfde4Th7 !!
ça fonctionne bien, merci encore une fois !! =D

Juste un petit point en plus, mais pas grave si ça devient beaucoup plus compliqué, c'est juste esthétique : Si l'ancre est sur la même page, est ce possible d'éviter que le défilement ne reprenne du haut de la page ? °^° Ou bien ça devient trop casse tête ? xD
MlleAlys

MlleAlys
Membre actif

Messages : 5767
Inscrit(e) le : 12/09/2012

MlleAlys a été remercié(e) par l'auteur de ce sujet.

Résolu Re: Décalage de l'affichage des ancres et défilement (javascript)

Message par Self Ven 13 Mar 2015 - 20:39

Je n'ai pas testé mais je suppose qu'en remplaçant le code par ceci ça devrait le faire :
Code:
jQuery(function($){
   var a = sessionStorage.getItem('anchor'), yPos, yInitPos, target;

   function scrolling(href){
          
      // On ajoute le hash dans l'url.
      window.location.hash = href;
                   
      // On cible manuellement l'ancre pour en extraire sa position.
      // Si c'est un ID on l'obtient.
      target = ($(href + ":first"));
               
      // Sinon on cherche l'ancre dans le name d'un a.
      if (target.length == 0) {
         target = ($("a[name=" + href.replace(/#/gi,"") + "]:first"))
      }
                   
      // Si on a trouvé un name ou un id, on défile.
      if (target.length == 1) {
         yPos = target.offset().top; // Position de l'ancre.
                   
         // On anime le défilement jusqu'à l'ancre.
         $('html,body').animate({ scrollTop: yPos - 40 }, 1000); // On décale de 40 pixels l'affichage pour ne pas coller le bord haut de l'affichage du navigateur et on défile en 1 seconde jusqu'à l'ancre.
      }
   }

   if(a){ var href = a; scrolling(a); sessionStorage.removeItem('anchor'); }
   // Pour tous les liens commençant par #.
   $("a").click(function (e) {

      var href = $(this).attr('href'), t = new RegExp('#.*'), anchor = new RegExp('^#.*');
      if(href.match(anchor)){ e.preventDefault(); scrolling(href); }else if(href.match(t)){
         e.preventDefault();
         sessionStorage.setItem('anchor', href.match(t));
         location.href = href.replace(/#.*/, '');
      }
   });
});
Self

Self
Membre actif

Masculin
Messages : 3853
Inscrit(e) le : 13/06/2013

https://selfback.forumactif.com/
Self a été remercié(e) par l'auteur de ce sujet.

Résolu Re: Décalage de l'affichage des ancres et défilement (javascript)

Message par MlleAlys Ven 13 Mar 2015 - 20:45

Je l'ai mis sur mon forum test, ça fonctionne toujours parfaitement pour les liens en href="#id"
Pour ceux en href="/blabla#id" ça ne remonte plus en haut de la page, mais ça affiche brutalement à hauteur de la div avant de remonter en défilant sur les 40px de décalage ^^"
MlleAlys

MlleAlys
Membre actif

Messages : 5767
Inscrit(e) le : 12/09/2012

MlleAlys a été remercié(e) par l'auteur de ce sujet.

Résolu Re: Décalage de l'affichage des ancres et défilement (javascript)

Message par Self Ven 13 Mar 2015 - 22:11

Peut-être avec ceci ? :
Code:
jQuery(function($){
   var a = sessionStorage.getItem('anchor'), yPos, yInitPos, target;

   function scrolling(href, p){

      yInitPos = $(window).scrollTop();

      // On ajoute le hash dans l'url.
      window.location.hash = href;

      // Comme il est possible que l'ajout du hash perturbe le défilement, on va forcer le scrollTop à son endroit inital.
      if(a) $(window).scrollTop(yInitPos);
      else $(window).scrollTop(p);

      
      // On cible manuellement l'ancre pour en extraire sa position.
      // Si c'est un ID on l'obtient.
      target = ($(href + ":first"));
               
      // Sinon on cherche l'ancre dans le name d'un a.
      if (target.length == 0) {
         target = ($("a[name=" + href.replace(/#/gi,"") + "]:first"))
      }
                   
      // Si on a trouvé un name ou un id, on défile.
      if (target.length == 1) {
         yPos = target.offset().top; // Position de l'ancre.
                   
         // On anime le défilement jusqu'à l'ancre.
         $('html,body').animate({ scrollTop: yPos - 40 }, 1000); // On décale de 40 pixels l'affichage pour ne pas coller le bord haut de l'affichage du navigateur et on défile en 1 seconde jusqu'à l'ancre.
      }
   }

   if(a){ var href = a; scrolling(a); sessionStorage.removeItem('anchor'); }
   // Pour tous les liens commençant par #.
   $("a").click(function (e) {

      var href = $(this).attr('href'), t = new RegExp('#.*'), anchor = new RegExp('^#.*'), p = $(this).offset().top;
      if(href.match(anchor)){ e.preventDefault(); scrolling(href, p); }else if(href.match(t)){
         e.preventDefault();
         sessionStorage.setItem('anchor', href.match(t));
         location.href = href.replace(/#.*/, '');
      }
   });
});
Self

Self
Membre actif

Masculin
Messages : 3853
Inscrit(e) le : 13/06/2013

https://selfback.forumactif.com/
Self a été remercié(e) par l'auteur de ce sujet.

Résolu Re: Décalage de l'affichage des ancres et défilement (javascript)

Message par MlleAlys Ven 13 Mar 2015 - 22:15

hmmmm non, le premier clic sur le lien de type "#id" ne défile pas, et celui de type "/blabla#id" démarre à nouveau du haut de la page... °^°
MlleAlys

MlleAlys
Membre actif

Messages : 5767
Inscrit(e) le : 12/09/2012

MlleAlys a été remercié(e) par l'auteur de ce sujet.

Résolu Re: Décalage de l'affichage des ancres et défilement (javascript)

Message par Self Ven 13 Mar 2015 - 22:29

Hum je ne reproduis pas pour les #id, as-tu une page en exemple ?
Self

Self
Membre actif

Masculin
Messages : 3853
Inscrit(e) le : 13/06/2013

https://selfback.forumactif.com/
Self a été remercié(e) par l'auteur de ce sujet.

Résolu Re: Décalage de l'affichage des ancres et défilement (javascript)

Message par MlleAlys Ven 13 Mar 2015 - 22:43

sur l'accueil de mon forum test :
http://forum-test-phpbb2.forumactif.org/
en cliquant sur le lien sur l'accueil #chatbox_top ça descend à la chatbox sans défilement
je remonte un peu sur ma page pour recliquer sur le lien ça descend sans défilement
puis si je clique sur /#chatbox_top ça remonte puis défile
puis à nouveau sur #chatbox_top ça défile cette fois comme il faut
et si je réactualise l'index simple ça recommence du début


EDIT : je viens de penser que les invités ne voient pas la cb, je vais mettre un autre lien ! xD

EDIT2 : voilà j'ai mis deux liens en bas de PA pour le haut de la PA,
du coup maintenant sur #id ça descend brusquement avant de remonter en défilant @.@
et le /blabla#id remonte toujours en haut de page avant de redescendre ^^
MlleAlys

MlleAlys
Membre actif

Messages : 5767
Inscrit(e) le : 12/09/2012

MlleAlys a été remercié(e) par l'auteur de ce sujet.

Résolu Re: Décalage de l'affichage des ancres et défilement (javascript)

Message par Self Ven 13 Mar 2015 - 23:30

Pour le problème des #id qui descendent brusquement ça devrait être réglé avec ce code :
Code:
jQuery(function($){
   var a = sessionStorage.getItem('anchor'), yPos, yInitPos, target;

   function scrolling(href, p){

      yInitPos = $(window).scrollTop();

      // On ajoute le hash dans l'url.
      window.location.hash = href;

      // Comme il est possible que l'ajout du hash perturbe le défilement, on va forcer le scrollTop à son endroit inital.
      if(a) $(window).scrollTop(yInitPos);
      else $(window).scrollTop(p);

      
      // On cible manuellement l'ancre pour en extraire sa position.
      // Si c'est un ID on l'obtient.
      target = ($(href + ":first"));
               
      // Sinon on cherche l'ancre dans le name d'un a.
      if (target.length == 0) {
         target = ($("a[name=" + href.replace(/#/gi,"") + "]:first"))
      }
                   
      // Si on a trouvé un name ou un id, on défile.
      if (target.length == 1) {
         yPos = target.offset().top; // Position de l'ancre.

         // On anime le défilement jusqu'à l'ancre.
         $('html,body').animate({ scrollTop: yPos - 40 }, 1000);
      }
   }

   if(a){ var href = a; scrolling(a); sessionStorage.removeItem('anchor'); }
   // Pour tous les liens commençant par #.
   $("a").click(function (e) {

      var href = $(this).attr('href'), t = new RegExp('#.*'), anchor = new RegExp('^#.*'), p = $(window).scrollTop();
      if(href.match(anchor)){ e.preventDefault(); scrolling(href, p); }else if(href.match(t)){
         e.preventDefault();
         sessionStorage.setItem('anchor', href.match(t));
         location.href = href.replace(/#.*/, '');
      }
   });
});

Par contre pour l'autre format tu veux dire quand c'est l'adresse de la même page il faudrait pas que ça démarre de nouveau en haut de la page ? Parce que dans ce cas la le plus simple c'est à la vérification si c'est la même page on ne recharge pas la page, ça t’irait ?
Self

Self
Membre actif

Masculin
Messages : 3853
Inscrit(e) le : 13/06/2013

https://selfback.forumactif.com/
Self a été remercié(e) par l'auteur de ce sujet.

Résolu Re: Décalage de l'affichage des ancres et défilement (javascript)

Message par MlleAlys Ven 13 Mar 2015 - 23:38

voilà c'est ça, plutôt que recharger la page et donc de réapparaitre en haut de page avant de redéfiler vers le bas, juste défiler vers l'ancre directement comme si c'était un un autre href="#id", sans recharger la page effectivement je suppose que c'est ça, désolée si je n'étais pas très claire ^^"

par contre avec #id maintenant ça ne semble pas afficher le même décalage de 40px sous le haut de l'écran ?

En gros le code de ce message là me semblait parfait sauf pour l'histoire du défilement des /blabla#id qui rechargeaient la page à chaque fois
MlleAlys

MlleAlys
Membre actif

Messages : 5767
Inscrit(e) le : 12/09/2012

MlleAlys a été remercié(e) par l'auteur de ce sujet.

Résolu Re: Décalage de l'affichage des ancres et défilement (javascript)

Message par Self Sam 14 Mar 2015 - 12:36

Je n'avais pas bien compris au début effectivement ^^.
Ce code devrait le faire d'après mes tests Wink :
Code:
jQuery(function($){
   var a = sessionStorage.getItem('anchor'), yPos, yInitPos, target, loc = location.pathname;

   function scrolling(href){

      yInitPos = $(window).scrollTop();
                   
      // On ajoute le hash dans l'url.
      window.location.hash = href;
                   
      // Comme il est possible que l'ajout du hash perturbe le défilement, on va forcer le scrollTop à son endroit inital.
      $(window).scrollTop(yInitPos);
                   
      // On cible manuellement l'ancre pour en extraire sa position.
      // Si c'est un ID on l'obtient.
      target = ($(href + ":first"));
               
      // Sinon on cherche l'ancre dans le name d'un a.
      if (target.length == 0) {
         target = ($("a[name=" + href.replace(/#/gi,"") + "]:first"))
      }
                   
      // Si on a trouvé un name ou un id, on défile.
      if (target.length == 1) {
         yPos = target.offset().top; // Position de l'ancre.
                   
         // On anime le défilement jusqu'à l'ancre.
         $('html,body').animate({ scrollTop: yPos - 40 }, 1000); // On décale de 40 pixels l'affichage pour ne pas coller le bord haut de l'affichage du navigateur et on défile en 1 seconde jusqu'à l'ancre.
      }
   }

   if(a){ var href = a; scrolling(a); sessionStorage.removeItem('anchor'); }
   // Pour tous les liens commençant par #.
   $("a").click(function (e) {

      var href = $(this).attr('href'), t = new RegExp('#.*'), anchor = new RegExp('^#.*');
      if(href.match(anchor)){
         e.preventDefault();
         scrolling(href);
      }else if(href.match(t)){
         e.preventDefault();
         if(href.match(loc)){
            var h = href.match(t)[0];
            scrolling(h);
         }else{
            sessionStorage.setItem('anchor', href.match(t));
            location.href = href.replace(/#.*/, '');
         }
      }
   });
});
Self

Self
Membre actif

Masculin
Messages : 3853
Inscrit(e) le : 13/06/2013

https://selfback.forumactif.com/
Self a été remercié(e) par l'auteur de ce sujet.

Résolu Re: Décalage de l'affichage des ancres et défilement (javascript)

Message par MlleAlys Sam 14 Mar 2015 - 12:42

Alors ça marche parfaitement pour quand c'est sur la même page maintenant, mais quand c'est sur une autre page (lien vers le dernier message d'un sujet par exemple) le lien ne fonctionne plus du tout par contre ^^"
MlleAlys

MlleAlys
Membre actif

Messages : 5767
Inscrit(e) le : 12/09/2012

MlleAlys a été remercié(e) par l'auteur de ce sujet.

Résolu Re: Décalage de l'affichage des ancres et défilement (javascript)

Message par Self Sam 14 Mar 2015 - 13:39

Effectivement, j'ai corrigé Wink :
Code:
jQuery(function($){
   var a = sessionStorage.getItem('anchor'), yPos, yInitPos, target, loc = location.pathname;

   function scrolling(href){

      yInitPos = $(window).scrollTop();
                   
      // On ajoute le hash dans l'url.
      window.location.hash = href;
                   
      // Comme il est possible que l'ajout du hash perturbe le défilement, on va forcer le scrollTop à son endroit inital.
      $(window).scrollTop(yInitPos);
                   
      // On cible manuellement l'ancre pour en extraire sa position.
      // Si c'est un ID on l'obtient.
      target = ($(href + ":first"));
               
      // Sinon on cherche l'ancre dans le name d'un a.
      if (target.length == 0) {
         target = ($("a[name=" + href.replace(/#/gi,"") + "]:first"))
      }
                   
      // Si on a trouvé un name ou un id, on défile.
      if (target.length == 1) {
         yPos = target.offset().top; // Position de l'ancre.
                   
         // On anime le défilement jusqu'à l'ancre.
         $('html,body').animate({ scrollTop: yPos - 40 }, 1000); // On décale de 40 pixels l'affichage pour ne pas coller le bord haut de l'affichage du navigateur et on défile en 1 seconde jusqu'à l'ancre.
      }
   }

   if(a){ var href = a; scrolling(a); sessionStorage.removeItem('anchor'); }
   // Pour tous les liens commençant par #.
   $("a").click(function (e) {

      var href = $(this).attr('href'), t = new RegExp('#.*'), anchor = new RegExp('^#.*');
      if(href.match(anchor)){
         e.preventDefault();
         scrolling(href);
      }else if(href.match(t)){
         e.preventDefault();
         var l = new RegExp('\\/[a-z0-9-]*');
         if(href.match(l)[0] == loc){
            var h = href.match(t)[0];
            scrolling(h);
         }else{
            sessionStorage.setItem('anchor', href.match(t));
            location.href = href.replace(/#.*/, '');
         }
      }
   });
});
Self

Self
Membre actif

Masculin
Messages : 3853
Inscrit(e) le : 13/06/2013

https://selfback.forumactif.com/
Self a été remercié(e) par l'auteur de ce sujet.

Résolu Re: Décalage de l'affichage des ancres et défilement (javascript)

Message par MlleAlys Sam 14 Mar 2015 - 14:53

ça fonctionne parfaitement, merci beaucoup encore une fois !!!! Flowers2
Je passe le sujet en résolu ! :thanks:
MlleAlys

MlleAlys
Membre actif

Messages : 5767
Inscrit(e) le : 12/09/2012

MlleAlys a été remercié(e) par l'auteur de ce sujet.

Voir le sujet précédent Voir le sujet suivant Revenir en haut

- Sujets similaires

Permission de ce forum:
Vous ne pouvez pas répondre aux sujets dans ce forum