我认为您的问题仅与词缀有关。我在 3 种情况下发现了问题:
- 没有滚动并单击链接
- 点击第一个链接
- scoll,单击第一个链接,然后单击另一个链接。
在这三种情况下,您从未应用词缀的位置单击到应用了词缀的位置。
您的点击会将目标锚点滚动到页面顶部并在此之后应用词缀(将导航栏的位置设置为固定)会发生什么。结果导航栏与内容重叠。
我认为您不能仅使用 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();
因为您已经使用数据属性设置了滚动间谍。
另见:https ://github.com/twbs/bootstrap/issues/10670
删除此硬编码值
当单击内部链接(以#{id} 开头)时,id={id} 的锚点将滚动到视口的顶部。在这种情况下,会有一个固定的导航栏(词缀),所以锚应该滚动到顶部减去导航栏的高度。导航栏的高度为 85 像素(品牌形象的 63 像素 + 边框的 2 像素 + .navbarheader 的 20 像素的边距底部)
此值将在此处使用:
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")固定导航栏的高度未用于计算,因此该点将为 443 - 85 ( navbarheight) = 378。此代码可以替换为。
if(scrollTop==(443-navbarheight))
{
this.$window.scrollTop(scrollTop+navbarheight);
}
Note 443 现在仍将被硬编码。它还在您的 html 中使用 affix-top 进行硬编码。
注意用上面的值替换是行不通的。(af)fixed 和 not 之间的情况会因每个滚动动作而改变。该部分if(scrollTop==378)
是一个技巧而不是解决方案。它解决了 scrollheight < data-offset-top 的情况。我们不能应用整个范围,在这种情况下,用户不能永远滚动回顶部(this.$window.scrollTop 一次又一次地滚动他)。
navbarheight 的计算也很棘手。当导航栏固定 $('#nav').innerHeight() / height 将返回 85(包括边距)。在绝对位置,这将是 65。