Bootstrap词缀导航栏用于带有scrollspy和页面锚点的单页 [英] Bootstrap affix navbar for single page with scrollspy and page anchors
问题描述
这是一个页面,其中的导航栏仅链接到本地锚点.
导航栏位于标题之后,但在向下滚动时会停留在顶部.
This is for a single page, with a navbar that links to local anchors only.
The navbar comes after a header, but sticks to top when scrolling down.
You can see how it works on github pages
但是链接/锚点存在两个偏移问题:
But I've got two offset problems with link/anchors:
- 只要您不滚动,锚点就会被导航栏偏移并掩盖.
- 粘贴导航栏后,以下链接将按预期运行,但第一个链接无效.
由于页边距阻止标题从顶部开始,因此页边空白破坏了布局:
A body margin breaks the layout as it prevents the header from beginning right at the top:
body {
margin-top: 65px;
}
我尝试了以下部分的边距/填充操作:
I've tried without success to play with margin/padding for the sections:
section {
padding-top: 65px;
margin-top: -65px;
}
这是 html 和
我认为您的问题仅与词缀有关.我在3种情况下发现了问题: I think your problem has only to do with the affix. I found a problem in 3 situations: 在这三种情况下,您从未应用词缀的位置单击到已应用词缀的位置. In this three situation you click from an position where you affix is not applied to a position where your affix has been applied. 单击将目标锚点滚动到页面顶部并在其后应用词缀(将导航栏的位置设置为固定)会发生什么.结果导航栏与内容重叠. What happens your click scrolls the target anchor to the top of the page and applies the affix (set navbar's position to fixed) after this. Result the navbar overlaps the content. 我认为您不能仅使用CSS来解决此问题.我认为您为该部分添加页边距/填充的解决方案是正确的,但是您必须在词缀后应用页边距. I don't think you could fix this with css only. I think your solution of adding a margin / padding to the section will be right, but you will have to apply the margin after the affix. 我尝试过类似的事情: 这感觉很复杂,现在似乎只能在Firefox上使用. This feels to complex and also only seems to work on firefox now. 更新 我认为我可以通过覆盖完整的词缀checkPosition函数来解决您的问题: I think i could fix your problem by overwritting the complete affix checkPosition function: 有些值已经过硬编码(现在),因此此功能仅适用于github页面上的示例. Some values are hard coded (now) so this function only will work for your example on github pages. 在github页面上,您使用jQuery和Bootstrap的旧"版本.您无需为scrollspy设置偏移量.您不必调用 On github pages you use "old" versions of jQuery and Bootstrap. You don't need to set an offset for the scrollspy. You don't have to call 另请参阅: https://github.com/twbs/bootstrap/issues/10670 删除此硬编码值 单击内部链接(以#{id}开头)时,id = {id}的锚点将滚动到视口顶部.
在这种情况下,将有一个固定的导航栏(词缀),因此锚点应滚动到顶部减去导航栏的高度.
导航栏的高度将为85px(品牌图片的63像素+边框的2像素+ .navbarheader的20 px的边距底部) When clicking an internal link (start with #{id}) the anchor with id={id} will be scrolled to the top of the viewport.
In this case there will be a fixed navbar (affix) so the anchor should scroll to the top minus the height of the navbar.
The height of the navbar will be 85px (63 pixels of the brand image + 2 pixels of the border + the margin-bottom of 20 px of the .navbarheader) 此值将在此处使用: 我用过83(可能看起来更好吗?).
因此83可以替换为: I have used 83 (may look better?).
So the 83 can be replaced with: 那么我们有这些: (第一个)链接将锚点滚动到没有词缀的顶部
已应用(在data-offset-top ="443"以下)固定高度
导航栏未用于计算,因此该点将为443-85
(navbarheight)=378.此代码可以替换为. The (first) link scrolls the anchor to the top where the affix is not
applied yet (below data-offset-top="443") the height of your fixed
navbar is not used in calculacting so this point will be 443 - 85
(navbarheight) = 378. This code could be replace with. 注释443现在仍将被硬编码.它也硬编码在您的
带有affix-top的html. Note 443 now still will be hardcoded. It is also hardcoded in your
html with affix-top. 当心用上述值替换值将不起作用.这
(af)固定和不固定之间的情况将随着每次滚动而改变
行动. Watch out Replacing the values with the above won't work. The
situation between (af)fixed and not will change for every scroll
action. The part navbarheight的计算也很棘手.当导航栏
固定$('#nav').innerHeight()/高度将返回85(包括
保证金).绝对位置是65. Also the calculation of navbarheight will be tricky. When the navbar
is fixed $('#nav').innerHeight() / height will return 85 (including
the margin). In the absolute position this will be 65. 这篇关于Bootstrap词缀导航栏用于带有scrollspy和页面锚点的单页的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!推荐答案
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++;
}
$.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() })
}
}
$('#navbar').scrollspy();
,因为您已经使用数据属性设置了scrollspy.$('#navbar').scrollspy();
also cause you already set the scrollspy with data attributes.if(scrollTop > offsetTop) {$('#content').css('margin-top','83px'); console.log('margin') }
else{$('#content').css('margin-top','0');}
var navbarheight = $('#nav').innerHeight()
var navbarheight = $('#nav').innerHeight()
if(scrollTop==378)
{
this.$window.scrollTop('463');
scrollTop==463;//typo?? make no sense
}
if(scrollTop==(443-navbarheight))
{
this.$window.scrollTop(scrollTop+navbarheight);
}
if(scrollTop==378)
部分是技巧而不是解决方案.它
解决滚动高度<数据偏移量最高.我们不能
应用整个范围,在这种情况下,用户永远无法滚动
返回顶部(this.$ window.scrollTop一次又一次地向后滚动他).if(scrollTop==378)
is a trick not a solution. It
solves the situation for scrollheight < data-offset-top. We could not
apply the whole range, case in that case the user can't never scroll
back to the top (this.$window.scrollTop scrolls him back again and again).