我认为您的问题仅与词缀有关。我在 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")固定的高度
navbar 不用于计算,所以这一点将是 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
navbarheight 的计算也很棘手。当导航栏
固定 $('#nav').innerHeight() / 高度将返回 85(包括
边距)。在绝对位置上,这将是 65。