Как добавить плавную прокрутку к функции шпионажа Bootstrap

Я уже некоторое время пытаюсь добавить функцию плавной прокрутки на свой сайт, но не могу заставить ее работать.

Вот мой HTML-код, относящийся к моей навигации:

<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-->

Вот код JS, который я добавил:

<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>

Для чего это стоит, здесь, где я получил информацию о том, что я сделал до сих пор, и здесь - мой сайт в его текущей форме. Если ты поможешь мне, я испеку тебе пирог, печенье или еще что-нибудь. Спасибо!

Ответ 1

Вам действительно нужен этот плагин? Вы можете просто оживить свойство 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;
     });

});

fiddle

Ответ 2

Если у вас есть фиксированная навигационная панель, вам понадобится что-то вроде этого.

Взятие из лучшего из приведенных выше ответов и комментариев...

$(".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);
  });
});

Во-первых, чтобы предотвратить ошибку "undefined", сохраните хеш переменной, target, перед вызовом preventDefault(), а затем ссылайтесь на это сохраненное значение, как указано pupadupa.

Далее. Вы не можете использовать window.location.hash = target, потому что он устанавливает URL и местоположение одновременно, а не отдельно. У вас будет место в начале элемента, чей идентификатор совпадает с href... но покрыт вашей фиксированной верхней навигационной панелью.

Чтобы обойти это, вы устанавливаете значение scrollTop в значение местоположения вертикальной прокрутки цели за вычетом высоты фиксированного навигатора. Прямое таргетирование на это значение поддерживает плавную прокрутку, вместо того, чтобы впоследствии добавлять корректировку и получать неудобные дрожания.

Вы заметите, что URL-адрес не изменяется. Чтобы установить это, вместо этого используйте return window.history.pushState(null, null, target);, чтобы вручную добавить url в стек истории.

Готово!

Другие примечания:

1) с использованием метода .on является последним (по состоянию на январь 2015 г.) методом jquery, который лучше, чем .bind или .live, или даже .click по причинам, которые я оставлю вам, чтобы узнать.

2) значение navOffset может находиться внутри функции или снаружи, но вы, вероятно, захотите ее на улице, так как вы можете очень хорошо ссылаться на это вертикальное пространство для других манипуляций с функциями /DOM. Но я оставил его внутри, чтобы сделать его аккуратно в одну функцию.

Ответ 3

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

Ответ 4

Если вы загрузите плагин jquery easing (проверьте его), вам просто нужно добавить это в свой файл 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();
});

а также не забудьте добавить класс гладкой прокрутки к вашим тегам следующим образом:

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

Ответ 5

Я объединил его, и это результаты -

$(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;
         });
      }
    }
  });
});

Я тестировал его, и он отлично работает. надеюсь, это поможет кому-то:)

Ответ 6

Отправлено onetrickpony, но если вы хотите иметь более общее решение, вы можете просто использовать код ниже.

Вместо того, чтобы выбрать только id якоря, вы можете сделать его более стандартным и просто выбрать атрибут name <a> -Tag. Это избавит вас от написания дополнительного тега id. Просто добавьте класс smoothscroll к элементу navbar.

Что изменилось

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

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

Конечный код

/* 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;

  });
});