jQuery faites défiler jusqu'à l'ancre (moins la quantité de pixels)

j'utilise le code suivant pour faire défiler les points d'ancrage avec jQuery:

$(document).ready(function() {
  function filterPath(string) {
  return string
    .replace(/^//,'')
    .replace(/(index|default).[a-zA-Z]{3,4}$/,'')
    .replace(//$/,'');
  }
  var locationPath = filterPath(location.pathname);
  var scrollElem = scrollableElement('html', 'body');

  $('a[href*=#]').each(function() {
    var thisPath = filterPath(this.pathname) || locationPath;
    if (  locationPath == thisPath
    && (location.hostname == this.hostname || !this.hostname)
    && this.hash.replace(/#/,'') ) {
      var $target = $(this.hash), target = this.hash;
      if (target) {
        var targetOffset = $target.offset().top;
        $(this).click(function(event) {
          event.preventDefault();
          $(scrollElem).animate({scrollTop: targetOffset}, 400, function() {
            location.hash = target;
          });
        });
      }
    }
  });

  // use the first element that is "scrollable"
  function scrollableElement(els) {
    for (var i = 0, argLength = arguments.length; i <argLength; i++) {
      var el = arguments[i],
          $scrollElement = $(el);
      if ($scrollElement.scrollTop()> 0) {
        return el;
      } else {
        $scrollElement.scrollTop(1);
        var isScrollable = $scrollElement.scrollTop()> 0;
        $scrollElement.scrollTop(0);
        if (isScrollable) {
          return el;
        }
      }
    }
    return [];
  }

});

y a-t-il de toute façon pour le faire défiler jusqu'à l'ancre mais moins une quantité définie de pixels? (dans mon cas, je veux qu'il aille -92px)

Merci pour votre aide.

27
demandé sur John 2012-07-06 19:21:46

8 réponses

j'ai juste eu à résoudre ce problème moi-même. Vous devez ajuster votre offset par le nombre de pixels que vous voulez scrollTo. Dans mon cas, j'avais besoin que ce soit 50 pixels plus haut sur la page. Donc, j'ai soustrait 50 de targetOffset.

maintenant, la partie du code qui vous fait vaciller est l'emplacement.hachage - c'est dire au navigateur de régler son emplacement à un point précis. Dans tous les cas, il s'agit d'une chaîne contenant L'ID vers lequel vous venez de passer. Donc, ce serait quelque chose comme "#foo". Vous devez maintenir ceci, donc nous le laisserons.

Toutefois, pour empêcher le navigateur de "sauter" lorsque l'emplacement.le hachage est défini (une action par défaut du navigateur), vous avez simplement besoin d'empêcher l'action par défaut. Ainsi, passez votre événement ' e ' à travers la fonction completion dans la fonction animate. Puis il suffit d'appeler e.preventDefault(). Vous devez vous assurer que le navigateur appelle effectivement un événement, sinon il va faire une erreur. Donc, un si-test corrige ça.

fait. Voici la version révisée de la code chunk:

if (target) {
    var targetOffset = $target.offset().top - 50;
    $(this).click(function(event) {
      if(event != 'undefined') {
          event.preventDefault();}
      $(scrollElem).animate({scrollTop: targetOffset}, 400, function(e) {
          e.preventDefault();
          location.hash = target;
      });
    });
  }
28
répondu Jonathan Savage 2012-10-03 16:28:44

C'est ce que j'utilise:

function scrollToDiv(element){
    element = element.replace("link", "");
    $('html,body').unbind().animate({scrollTop: $(element).offset().top-50},'slow');
};

...où 50 est le nombre de pixels à ajouter/soustraire.

16
répondu kaleazy 2013-11-06 13:28:02

ce code fonctionne pour moi dans n'importe quel lien ancre dans mon site respect "150px" hauteur pour fix menu sur le dessus.

<!-- SMOOTH SCROLL -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script>
$(function() {
  $('a[href*=#]:not([href=#])').click(function() {
    if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') && location.hostname == this.hostname) {
      var target = $(this.hash);
      target = target.length ? target : $('[name=' + this.hash.slice(1) +']');
      if (target.length) {
        $('html,body').animate({
          scrollTop: target.offset().top-150
        }, 1000);
        return false;
      }
    }
  });
});
</script>
<!-- End of SMOOTH SCROLL -->
9
répondu Max 2015-08-27 20:12:47

Lol)

<span class="anchor" id="section1"></span>
<div class="section"></div>

<span class="anchor" id="section2"></span>
<div class="section"></div>

<span class="anchor" id="section3"></span>
<div class="section"></div>

<style>
.anchor{
  display: block;
  height: 115px; /*same height as header*/
  margin-top: -115px; /*same height as header*/
  visibility: hidden;
}
</style>
5
répondu Никита Андрейчук 2015-03-19 13:58:35

Je n'ai pas pu utiliser la solution de Jonathan Savage car je ne pouvais pas passer un appel d'événement dans animate() sans erreur. J'ai eu ce problème aujourd'hui et j'ai trouvé une solution simple:

      var $target = $(this.hash), target = this.hash;
      if (target) {
        var targetOffset = $target.offset().top - 92;
        $(this).click(function(event) {
          event.preventDefault();
          $(scrollElem).animate({scrollTop: targetOffset}, 400, function() {
            location.hash = targetOffset;
          });
        });

soustrayez votre décalage de pixel de la variable targetOffset, puis assignez l'emplacement.hachez cette variable. Arrête le saut de page en défilant vers le hachage cible.

1
répondu vibrationbaby 2014-10-13 04:31:40

il s'agit d'une implémentation jQuery que j'utilise et qui était basée sur la solution de Никита Андрейчук. La variable d'ajustement du pixel peut être définie dynamiquement de cette façon, bien qu'elle soit codée en dur dans cet exemple.

$( 'a' ).each(function() {
    var pixels = 145;
    var name = $( this ).attr( 'name' );
    if ( typeof name != 'undefined' ) {
        $( this ).css({
          'display'    : 'block',
          'height'     : pixels + 'px',
          'margin-top' : '-' + pixels + 'px',
          'visibility' : 'hidden'
        });
    }
});
0
répondu Jeremy Morgan 2016-06-01 15:35:34

Voici ce que j'utilise. Réglez le offset sur ce dont vous avez besoin.

$('a[href^="#"]').click(function(e) {
  e.preventDefault();
  $(window).stop(true).scrollTo(this.hash {duration:1000,interrupt:true,offset: -50});
});
0
répondu C. Bruchesi 2017-05-17 12:54:05

ne pas vouloir apprendre le Javascript et toujours à la recherche de l'option la plus facile, il suffit de créer un DIV vide au-dessus du point d'ancrage où vous voulez atterrir puis dans CSS faire le div

anchorpointl{margin-top: - 115px;}

ou bien au-dessus ou au-dessous de vous voulez aller et de l'emploi qui fait

-1
répondu nick 2018-08-13 02:10:30