如何为 Bootstrap 的 scroll spy 功能添加平滑滚动

Posted

技术标签:

【中文标题】如何为 Bootstrap 的 scroll spy 功能添加平滑滚动【英文标题】:How to add smooth scrolling to Bootstrap's scroll spy function 【发布时间】:2013-01-26 03:06:47 【问题描述】:

一段时间以来,我一直在尝试向我的网站添加平滑滚动功能,但似乎无法使其正常工作。

这是与导航相关的 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>

对于它的价值,here 是我收到关于我到目前为止所做的信息的地方,here 是我当前形式的网站。如果你能帮助我,我会给你烤一个馅饼或饼干之类的。谢谢!

【问题讨论】:

还有this jQuery plugin that might make your life easier 这是一个简单的 Bootstrap 3.x 模板codeply.com/go/k9CEVobeY6 【参考方案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

【讨论】:

当所有链接都指向同一页面中的锚点时,这很有效,但如果包含外部链接,它们将不再有效。对于它只对锚点进行操作并保留真实链接操作使用:$("#nav ul li a[href^='#']").bind('click'').bind(...) 不错,@Dologan - 我编辑了结果并将bind 更改为on 我的问题 1 不在 Bootstrap 中。 AddThis 插件会导致该问题。这是一个解决方案:support.addthis.com/customer/portal/articles/… 为了解决 undefinde 问题,我这样做:1)在e.preventDefault(); 之前添加这一行target = this.hash; 2)将window.location.hash = this.hash; 行更改为window.location.hash = target; 请注意,要使其正常工作,您需要使用 &lt;a id="..."&gt; 作为锚点,而不是通常的 &lt;a name="..."&gt;(尽管您可以添加这两个属性作为后备)。【参考方案2】:

onetrickpony 发的还可以,但是如果你想有一个更通用的解决方案,你可以使用下面的代码。

除了选择锚点的id,您还可以让它更像标准,只选择&lt;a&gt;-Tag 的属性name。这将使您免于编写额外的id 标签。只需将 smoothscroll 类添加到导航栏元素即可。

发生了什么变化

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;

  );
);

【讨论】:

【参考方案3】:

如果你有一个固定的导航栏,你会需要这样的东西。

从上述答案和 cmets 中汲取精华...

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

首先,为了防止“未定义”错误,在调用 preventDefault() 之前,将哈希存储到变量 target,然后引用该存储的值,如 pupadupa 所述。

接下来。您不能使用window.location.hash = target,因为它同时而不是单独设置 url 和位置。您最终将在 id 与 href 匹配的元素的开头找到该位置...但被您的固定顶部导航栏覆盖。

为了解决这个问题,您将 scrollTop 值设置为目标的垂直滚动位置值减去固定导航栏的高度。直接定位该值可保持平滑滚动,而不是事后添加调整,并获得看起来不专业的抖动。

您会注意到 url 没有改变。要设置它,请改用return window.history.pushState(null, null, target);,手动将 url 添加到历史堆栈。

完成!

其他说明:

1) 使用.on 方法是最新的(截至2015 年1 月)jquery 方法,它优于.bind.live,甚至.click,原因我将留给您了解.

2) navOffset 值可以在函数内部或外部,但您可能希望它在外部,因为您很可能会为其他函数/DOM 操作引用该垂直空间。但是我把它留在了里面,让它整齐地变成一个函数。

【讨论】:

【参考方案4】:
$("#YOUR-BUTTON").on('click', function(e) 
   e.preventDefault();
   $('html, body').animate(
        scrollTop: $("#YOUR-TARGET").offset().top
     , 300);
);

【讨论】:

这段代码有什么作用?你能改进这个答案吗? 这使用jquery,如果你不使用jquery,这将不起作用。【参考方案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;
         );
      
    
  );
);

我测试了它,它工作正常。希望这会对某人有所帮助:)

【讨论】:

虽然这段代码 sn-p 可以解决问题,但including an explanation 确实有助于提高帖子的质量。请记住,您是在为将来的读者回答问题,而这些人可能不知道您提出代码建议的原因。【参考方案6】:

如果你下载了 jquery easing 插件(check it out),那么你只需要将它添加到你的 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();
);

并且不要忘记将平滑滚动类添加到您的 a 标签中,如下所示:

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

【讨论】:

【参考方案7】:
// styles.css
html 
    scroll-behavior: smooth

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

【讨论】:

【参考方案8】:

使用此代码,id 不会出现在链接上

    document.querySelectorAll('a[href^="#"]').forEach(anchor => 
        anchor.addEventListener('click', function (e) 
            e.preventDefault();

            document.querySelector(this.getAttribute('href')).scrollIntoView(
                behavior: 'smooth'
            );
        );
    );

【讨论】:

以上是关于如何为 Bootstrap 的 scroll spy 功能添加平滑滚动的主要内容,如果未能解决你的问题,请参考以下文章

如何为缩略图悬停添加标题 - Bootstrap?

Bootstrap:如何为每个屏幕宽度指定不同的背景颜色?

如何为 Bootstrap 模式窗口指定主要和次要操作?

如何为 Bootstrap 表行添加边距?

如何为 SAML SP 元数据使用 Tomcat SSL 证书

如何为 Bootstrap 实现支持拖放的触摸敏感、响应式、可排序列表?