带有scrollspy和页面锚点的Bootstrap词缀导航栏单页面

时间:2013-09-14 08:07:59

标签: single-page-application navbar twitter-bootstrap-3 scrollspy affix

这是针对单个页面的,只有链接到本地​​锚点的导航栏 导航栏位于标题之后,但在向下滚动时会粘到顶部。

您可以看到它是如何运作的on github pages

但我有链接/锚点的两个偏移问题:

  • 只要您不滚动,锚点就会被导航栏偏移并屏蔽。
  • 添加导航栏后,以下链接按预期工作,但不是第一个。

身体边距会破坏布局,因为它会阻止标题从顶部开始:

body {
    margin-top: 65px;
}

我尝试过没有成功使用边距的边距/填充:

section {
    padding-top: 65px;
    margin-top: -65px; 
}

以下是htmlcss

  • 知道怎么解决这个问题吗?
  • 可以用纯CSS解决吗?
  • 或者我需要一些js修复来解释词缀吗?

1 个答案:

答案 0 :(得分:2)

我认为你的问题只与词缀有关。我在3种情况下发现了一个问题:

  1. 无滚动并点击链接
  2. 点击第一个链接
  3. scoll,点击第一个链接,然后点击其他链接。
  4. 在这三种情况下,您从没有应用词缀的位置单击您所加词缀的位置。

    您的点击会将目标锚点滚动到页面顶部并在此之后应用词缀(将导航栏的位置设置为固定)。结果导航栏与内容重叠。

    我认为你不能用css解决这个问题。我认为你在该部分添加保证金/填充的解决方案是正确的,但你必须在词缀后应用保证金。

    我尝试过类似的事情:

    var tmp = $.fn.affix.Constructor.prototype.checkPosition;
    var i = 0;
    var correct = false
    $.fn.affix.Constructor.prototype.checkPosition = function () {
      $('#content').css('margin-top','0');
      tmp.call(this);
    
      if(i%2!=0 && $(window).scrollTop()<443){correct=true}
      if(i%2==0 && correct){$('#content').css('margin-top','83px').trigger('create'); correct=false}
      i++;
    }
    

    这感觉很复杂,现在似乎只能在firefox上运行。

    <强>更新

    我想我可以通过覆盖完整的词缀checkPosition函数来解决你的问题:

    $.fn.affix.Constructor.prototype.checkPosition = function () 
    {
        if (!this.$element.is(':visible')) return
    
        var scrollHeight = $(document).height()
        var scrollTop    = this.$window.scrollTop()
        var position     = this.$element.offset()
        var offset       = this.options.offset
        var offsetTop    = offset.top
        var offsetBottom = offset.bottom
        if(scrollTop==378) 
        {
        this.$window.scrollTop('463');
        scrollTop==463;
        }
        if (typeof offset != 'object')         offsetBottom = offsetTop = offset
        if (typeof offsetTop == 'function')    offsetTop    = offset.top()
        if (typeof offsetBottom == 'function') offsetBottom = offset.bottom()
    
        var affix = this.unpin   != null && (scrollTop + this.unpin <= position.top) ? false :
                    offsetBottom != null && (position.top + this.$element.height() >= scrollHeight - offsetBottom) ? 'bottom' :
                    offsetTop    != null && (scrollTop <= offsetTop) ? 'top' : false
        console.log(scrollTop + ':' + offsetTop);
    
        if(scrollTop > offsetTop) {$('#content').css('margin-top','83px'); console.log('margin') }
        else{$('#content').css('margin-top','0');}
        if (this.affixed === affix) return
    
        if (this.unpin) this.$element.css('top', '')
    
        this.affixed = affix
        this.unpin   = affix == 'bottom' ? position.top - scrollTop : null
    
        this.$element.removeClass('affix affix-top affix-bottom').addClass('affix' + (affix ? '-' + affix : ''))
    
        if (affix == 'bottom') {
          this.$element.offset({ top: document.body.offsetHeight - offsetBottom - this.$element.height() })
        }
    }
    

    某些值是硬编码的(现在),因此此函数仅适用于github页面上的示例。

    演示:http://bootply.com/81336

    在github页面上,您使用jQuery和Bootstrap的“旧”版本。您不需要为scrollspy设置偏移量。您也不必调用$('#navbar').scrollspy();,因为您已经使用数据属性设置了scrollspy。

    另请参阅:https://github.com/twbs/bootstrap/issues/10670

    删除此硬编码值

    单击内部链接(以#{id}开头)时,id = {id}的锚将滚动到视口顶部。 在这种情况下,将有一个固定的导航栏(附加),因此锚点应滚动到顶部减去导航栏的高度。 导航栏的高度为85px(品牌图像的63像素+边框的2个像素+ .navbarheader的20 px的边距底部)

    此值将在此处使用:

    if(scrollTop > offsetTop) {$('#content').css('margin-top','83px'); console.log('margin') }
    else{$('#content').css('margin-top','0');}
    

    我用了83(可能看起来更好?)。 所以83可以替换为:var navbarheight = $('#nav').innerHeight()

    然后我们有这些:

    if(scrollTop==378) 
    {
    this.$window.scrollTop('463');
    scrollTop==463;//typo?? make no sense
    } 
    

    (第一个)链接将锚点滚动到词缀所在的顶部 应用了(在data-offset-top =“443”之下)固定的高度 navbar不用于计算,所以这一点将是443 - 85 (navbarheight)= 378.此代码可以替换为。

    if(scrollTop==(443-navbarheight)) 
    {
    this.$window.scrollTop(scrollTop+navbarheight);
    }
    

    注443现在仍然是硬编码的。它也是硬编码的 html with affix-top。

    注意用上述代替值将不起作用。该 (af)固定与否之间的情况将随每个卷轴而变化 行动。部分if(scrollTop==378)是一个技巧而不是解决方案。它 解决了滚动高度的问题&lt;数据偏移顶。我们不能 应用整个范围,在这种情况下用户不能永远滚动 回到顶部(这个。$ window.scrollTop一次又一次地滚动回来)。

    导航高度的计算也很棘手。当导航栏 固定$('#nav')。innerHeight()/ height将返回85(包括 保证金)。在绝对位置,这将是65.