粘性标题滚动问题

13
我在网站上有一个粘性页眉。但是当视口底部下方的内容非常特定(大约等于我的html上2-3倍的padding-top)时,如果尝试缓慢滚动,则滚动会上下振荡。如果页面下方有大量内容,则它会正常工作。
编辑: 抱歉,如果我的原始问题不够清晰,但我希望整个页面可以滚动,直到“页眉”到达屏幕顶部,然后(仅此时)让页眉停止滚动,而页面其余内容继续在其后面滚动。
这里是一个JSfiddle

$(function () {
    // Check the initial Poistion of the Sticky Header
    var stickyHeaderTop = $('#stickyheader').offset().top;

    $(window).scroll(function () {
        if ($(window).scrollTop() > stickyHeaderTop) {
            $('#stickyheader').css({
                position: 'fixed',
                top: '0px'
            });
            $('#othercontent').css('margin-top', $('#stickyheader').outerHeight(true));
        } else {
            $('#stickyheader').css({
                position: 'static',
                top: '0px'
            });
            $('#othercontent').css('margin-top', '0px');
        }
    });
});
body {
    font: 13px sans-serif;
    padding-top: 20px;
}
#stickyheader {
    width: 100%;
    height: 40px;
    background:black;
    color:white;
    margin-bottom: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="stickyheader">Sticky header</div>
<div id="othercontent">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
</div>


我似乎无法复现所提到的振荡现象。您在哪个浏览器中看到这个问题?此外,这个问题有一些其他的解决方法,可以达到相同的效果https://dev59.com/YG025IYBdhLWcg3wnXWf#5903087。 - James Montagne
@JamesMontagne,我现在在运行Firefox 35和其他浏览器的OSX 10.9上看到了这个问题。你尝试过“运行代码片段”吗?由于屏幕大小不同,它经常不会显示在JSFiddle上。 - Erik Johnson
@ErikJohnson 我正在Linux上使用Firefox 31,也看不到你在说什么。 - Izkata
@izkata 我已经更新了问题中的代码,以使问题在我的机器上更加明显,你可以再次尝试运行代码片段吗? - Erik Johnson
@ErikJohnson 你是在说标题的宽度突然达到容器的右侧吗? 这是我能看到的唯一奇怪之处。垂直方向仍然没有跳动。 - Izkata
显示剩余4条评论
2个回答

10
你正在检查 if ($(window).scrollTop() > stickyHeaderTop),这使得头部在屏幕上方向上滚动一个像素,然后运行你的代码来更新CSS,接着CSS将其向下推。此外,你正在基于要修改的元素进行计算,导致抖动。先设置计算出的边距,然后对 #stickyheader 元素进行编辑。
$(function () {
    var stickyHeaderTop = $('#stickyheader').offset().top;

    $(window).scroll(function () {
        if ($(window).scrollTop() >= stickyHeaderTop) { // <-- Notice the greater than or equals to.
            $('#othercontent').css('margin-top', $('#stickyheader').outerHeight(true)); // <-- This has to be before the #stickyheader changes.
            $('#stickyheader').css({
                position: 'fixed',
                top: '0px'
            });
        } else {
            $('#stickyheader').css({
                position: 'static',
                top: '0px'
            });
            $('#othercontent').css('margin-top', '0px');
        }
    });
});

$(function () {
    var stickyHeaderTop = $('#stickyheader').offset().top;

    $(window).scroll(function () {
        if ($(window).scrollTop() >= stickyHeaderTop) {
            $('#othercontent').css('margin-top', $('#stickyheader').outerHeight(true));
            $('#stickyheader').css({
                position: 'fixed',
                top: '0px'
            });
        } else {
            $('#stickyheader').css({
                position: 'static',
                top: '0px'
            });
            $('#othercontent').css('margin-top', '0px');
        }
    });
});
body {
    font: 13px sans-serif;
    padding-top: 20px;
}
#stickyheader {
    width: 100%;
    height: 40px;
    background:black;
    color:white;
    margin-bottom: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="stickyheader">Sticky header</div>
<div id="othercontent">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
</div>


不幸的是,那并没有解决问题... 不过理论上听起来不错 :) - Erik Johnson
你能制作一个小的LICECap gif片段来说明你所经历的吗?上述代码修复了我浏览器上的振荡。(Safari 8.0.3) - ryebread
有趣!好的,我会试一试。 - Erik Johnson
没事了...我看到了不同的东西。现在我明白你的意思了。等一下,我会做出更多的改变。 - ryebread
1
@ErikJohnson,好的,我更新了答案以解决您的抖动问题。您正在基于一个正在更改的元素运行您的边距计算。这导致了抖动循环。 - ryebread
@ErikJohnson 现在ryebread已经确定了问题,修复它的另一种方法是将您的标题从静态变为绝对定位。这样,其他内容的边距将保持不变,无需在if/else中更改。我仍然无法重现这个问题,所以我无法测试它,但根据ryebread对问题的描述,这种方法也应该有效。 - James Montagne

0

我不确定为什么你编写了一个函数来管理滚动行为,当你可以使用一些HTML和CSS来实现你需要的效果。

更新的fiddle

body {
  font: 13px sans-serif;
  margin: 0px; <!-- container margin removed to prevent content appearing above -->
}
#stickyheader {
  width: 100%;
  height: 40px;
  background: black;
  color: white;
  position: fixed; <!-- add position fixed -->
  top: 0px; <!-- stick it to the top -->
}
#othercontent {
  padding-top: 50px; <!-- added to offset header -->
}
<div id="stickyheader">Sticky header</div>
<div id="othercontent">
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure
    dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure
    dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure
    dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure
    dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure
    dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure
    dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure
    dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure
    dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</p>
</div>

如果您有任何进一步的问题,本教程提供了所有必要的基础信息:

使用CSS创建固定标题


3
区别在于没有顶部填充 - 客户需要填充以及其他一些东西(如搜索栏)向上滚动并脱离屏幕,仅留下标题。 - Erik Johnson
@ErikJohnson 抱歉,但您在问题中从未说明这是一个要求,我只是向您展示了一种无需代码完成的选项。 - Tanner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接