web-dev-qa-db-fra.com

Comment ajouter un défilement régulier à la fonction Bootstrap scrollspy

Cela fait un moment que j'essaie d'ajouter une fonction de défilement régulier à mon site, mais je n'arrive pas à le faire fonctionner. 

Voici mon code HTML relatif à ma navigation:

<div id="nav-wrapper">
<div id="nav" class="navbar navbar-inverse affix-top" data-spy="affix" data-offset-top="675">
  <div class="navbar-inner" data-spy="affix-top">
    <div class="container">

      <!-- .btn-navbar is used as the toggle for collapsed navbar content -->
      <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </a>

      <!-- Everything you want hidden at 940px or less, place within here -->
      <div class="nav-collapse collapse">
        <ul class="nav">
            <li><a href="#home">Home</a></li>
            <li><a href="#service-top">Services</a></li>
            <li><a href="#contact-arrow">Contact</a></li>
        </ul><!--/.nav-->
      </div><!--/.nav-collapse collapse pull-right-->
    </div><!--/.container-->
  </div><!--/.navbar-inner-->
</div><!--/#nav /.navbar navbar-inverse-->
</div><!--/#nav-wrapper-->

Voici le code JS que j'ai ajouté:

<script src="js/jquery.scrollTo-1.4.3.1-min.js"></script>

<script>
    $(document).ready(function(e) {

        $('#nav').scrollSpy()
        $('#nav ul li a').bind('click', function(e) {
            e.preventDefault();
            target = this.hash;
            console.log(target);
            $.scrollTo(target, 1000);
        });
    });
</script>

Pour ce que cela vaut, ici est l'endroit où j'ai reçu des informations sur ce que j'ai fait jusqu'à présent, et ici est mon site sous sa forme actuelle. Si vous pouvez m'aider, je vais vous préparer une tarte, des biscuits ou autre chose. Merci!

64
Brian

Avez-vous vraiment besoin de ce plugin? Vous pouvez simplement animer la propriété scrollTop:

$("#nav ul li a[href^='#']").on('click', function(e) {

   // prevent default anchor click behavior
   e.preventDefault();

   // store hash
   var hash = this.hash;

   // animate
   $('html, body').animate({
       scrollTop: $(hash).offset().top
     }, 300, function(){

       // when done, add hash to url
       // (default click behaviour)
       window.location.hash = hash;
     });

});

violon

195
nice ass

Si vous avez une barre de navigation fixe, vous aurez besoin de quelque chose comme ça. 

Tirant profit des meilleures réponses et commentaires ci-dessus ...

$(".bs-js-navbar-scrollspy li a[href^='#']").on('click', function(event) {
  var target = this.hash;

  event.preventDefault();

  var navOffset = $('#navbar').height();

  return $('html, body').animate({
    scrollTop: $(this.hash).offset().top - navOffset
  }, 300, function() {
    return window.history.pushState(null, null, target);
  });
});

Tout d'abord, afin d'éviter l'erreur "non définie", enregistrez le hachage dans une variable, target, avant d'appeler preventDefault(), puis faites ultérieurement référence à cette valeur stockée, comme indiqué par pupadupa.

Suivant. Vous ne pouvez pas utiliser window.location.hash = target car il définit l'URL et l'emplacement simultanément plutôt que séparément. Vous allez finir par avoir l'emplacement au début de l'élément dont l'identifiant correspond à href ... mais couvert par votre barre de navigation supérieure fixe.

Afin de contourner ce problème, vous définissez votre valeur scrollTop sur la valeur d'emplacement de défilement vertical de la cible moins la hauteur de votre barre de navigation fixe. Le ciblage direct de cette valeur maintient le défilement en douceur, au lieu d’ajouter un ajustement par la suite et d’obtenir une instabilité peu professionnelle.

Vous remarquerez que l'URL ne change pas. Pour définir cela, utilisez plutôt return window.history.pushState(null, null, target);, pour ajouter manuellement l'URL à la pile d'historique.

Terminé!

Autres notes: 

1) utiliser la méthode .on est la dernière méthode (à compter de janvier 2015) meilleure que .bind ou .live, voire .click pour des raisons que je vous laisse découvrir.

2) la valeur navOffset peut être dans la fonction ou à l'extérieur, mais vous voudrez probablement la voir à l'extérieur, car vous pouvez très bien référencer cet espace vertical pour d'autres manipulations fonctions/DOM. Mais je l'ai laissé à l'intérieur pour en faire une fonction unique.

14
ahnbizcad
$("#YOUR-BUTTON").on('click', function(e) {
   e.preventDefault();
   $('html, body').animate({
        scrollTop: $("#YOUR-TARGET").offset().top
     }, 300);
});
8

Si vous téléchargez le plugin jquery easing (vérifiez-le) , il ne vous reste plus qu'à l'ajouter à votre fichier main.js:

$('a.smooth-scroll').on('click', function(event) {
    var $anchor = $(this);
    $('html, body').stop().animate({
        scrollTop: $($anchor.attr('href')).offset().top + 20
    }, 1500, 'easeInOutExpo');
    event.preventDefault();
});

et n'oubliez pas non plus d'ajouter la classe smooth-scroll à vos balises a comme ceci: 

 <li><a href="#about" class="smooth-scroll">About Us</a></li>
4
escolta13

Je l'ai combiné, et voici les résultats - 

$(document).ready(function() {
     $("#toTop").hide();

            // fade in & out
       $(window).scroll(function () {
                    if ($(this).scrollTop() > 400) {
                        $('#toTop').fadeIn();
                    } else {
                        $('#toTop').fadeOut();
                    }
                });     
  $('a[href*=#]').each(function() {
    if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'')
    && location.hostname == this.hostname
    && this.hash.replace(/#/,'') ) {
      var $targetId = $(this.hash), $targetAnchor = $('[name=' + this.hash.slice(1) +']');
      var $target = $targetId.length ? $targetId : $targetAnchor.length ? $targetAnchor : false;
       if ($target) {
         var targetOffset = $target.offset().top;
         $(this).click(function() {
           $('html, body').animate({scrollTop: targetOffset}, 400);
           return false;
         });
      }
    }
  });
});

Je l'ai testé et cela fonctionne bien. J'espère que cela aidera quelqu'un :)

3
genisugt

Ce que onetrickpony a publié est correct, mais si vous souhaitez une solution plus générale, vous pouvez simplement utiliser le code ci-dessous.

Au lieu de sélectionner uniquement la id de l'ancre, vous pouvez la rendre un peu plus standard et sélectionner simplement l'attribut name de la <a>- Tag. Cela vous évitera d'écrire une balise id supplémentaire. Ajoutez simplement la classe smoothscroll à l'élément navbar.

Qu'est ce qui a changé

1) $('#nav ul li a[href^="#"]') à $('#nav.smoothscroll ul li a[href^="#"]')

2) $(this.hash) à $('a[name="' + this.hash.replace('#', '') + '"]')

Code final

/* Enable smooth scrolling on all links with anchors */
$('#nav.smoothscroll ul li a[href^="#"]').on('click', function(e) {

  // prevent default anchor click behavior
  e.preventDefault();

  // store hash
  var hash = this.hash;

  // animate
  $('html, body').animate({
    scrollTop: $('a[name="' + this.hash.replace('#', '') + '"]').offset().top
  }, 300, function(){

    // when done, add hash to url
    // (default click behaviour)
    window.location.hash = hash;

  });
});
0
Patrick H.
// styles.css
html {
    scroll-behavior: smooth
}

Source: https://www.w3schools.com/howto/howto_css_smooth_scroll.asp#section2

0
James Akwuh