滚动页面时,如何使一个div在滚动到另一个div之后停留在页面顶部?

15
<div id="header"></div>
<div id="sticky"></div>
<div id="section"></div>
<div id="footer"></div>

<style>
  body { margin: 0px; background-color: #e3e3e3; }
  #header { background-color: #cb5454; height: 140px; }
  #sticky { background-color: #546bcb; height: 70px; }
  #section { height: 1500px; }
  #footer { background-color: #cb5454; height: 140px; }
</style>

这是我的代码:http://jsfiddle.net/uaqh018d/

我想让 #sticky 元素在滚动到 #header 之后固定在页面顶部。我还想它在未固定时保持隐藏。 然后,在向上滚动到 #header 后再次取消固定并隐藏。

我该如何实现这个效果?

4个回答

25

当你要将 #sticky 固定在屏幕顶部时,我建议给它添加一个类,并在需要“取消固定”时移除该类。然后,您可以在 CSS 中操作该类。

例如,对于类 fixed,您可以在 CSS 中添加以下内容:

#sticky {
    display: none;
    background-color: #546bcb;
    height: 70px;
}
#sticky.fixed {
    display: block;
    position: fixed;
    top: 0;
    width: 100%;
}

然后您的jQuery将如下所示:

$(window).scroll(function() {
    var distanceFromTop = $(this).scrollTop();
    if (distanceFromTop >= $('#header').height()) {
        $('#sticky').addClass('fixed');
    } else {
        $('#sticky').removeClass('fixed');
    }
});

这里是一个更新的 FIDDLE

我也可以建议一些 jQuery 淡入淡出或滑动效果(请参见 fiddle)。


谢谢!我相信这会更有效率! - John
高度是动态的而且未知的是什么? - SearchForKnowledge
@SearchForKnowledge 你是指粘性标题栏的高度吗?http://jsfiddle.net/uaqh018d/40/ - bowheart
我一直收到这个错误:Uncaught TypeError: Cannot read property 'scroll' of null - Si8
在 Fiddle 链接中的淡出选项会使菜单在回滚到顶部时消失。 - Saghachi

5
你可以使用position: fixed,并在JavaScript中检测用户滚动,如下所示:

$(document).scroll(function() {
  //detect when user scroll to top and set position to relative else sets position to fixed
  $("#sticky").css({
    "top": "0",
    "position": $(this).scrollTop() > 140 ? "fixed" : "relative"
  });
});
body {
  margin: 0px;
  background-color: #e3e3e3;
}
#header {
  background-color: #cb5454;
  height: 140px;
}
#sticky {
  background-color: #546bcb;
  height: 70px;
  width: 100%;
  position: fixed;
}
#section {
  height: 1500px;
}
#footer {
  background-color: #cb5454;
  height: 140px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="header"></div>
<div id="sticky"></div>
<div id="section"></div>
<div id="footer"></div>

References

.scroll()


几乎了,我们快成功了。我只需要让它在你向上滚动到#header底部时解除粘连,而不是当你滚动到页面顶部时解除粘连。 - John
2
哦,好了!你的小提琴现在正常工作了。谢谢,伙计!我不得不接受bowheart的答案。它似乎更有效率,但再次感谢! - John

1

嘿,这是一个旧问题,但对于新访客,我认为您只需要将此CSS代码添加到#sticky:

#sticky { position:sticky;top:0; }

我不需要JavaScript。

sticky根据滚动位置在相对定位和固定定位之间切换。

同时,父元素也不应该有overflow属性。


1
在我的情况下,我想要固定的div位于另一个div内部(即不是固定在页面上,而是在页面侧面的另一个固定div内)。以下是我对@bowhart的答案进行改编以解决这个问题的React组件(sticky_adapter.js):
module.exports.makeItSticky = function(thisReactComponent, parentScrollNode = window) {
  const thisNode = $(ReactDOM.findDOMNode(thisReactComponent));
  const position = thisNode.position();

  // Uncomment for verbose logging
  //console.log("Initial position: " + UIUtils.stringify(position));

  const scrollContainer = $(parentScrollNode);
  scrollContainer.scroll(() => {
    const distanceFromTop = scrollContainer.scrollTop();
    // Uncomment for verbose logging
    //console.log("ScrollTop: " + distanceFromTop);

    if (distanceFromTop > position.top) {
      thisNode.addClass("stick-to-top");
    } else {
      thisNode.removeClass("stick-to-top");
    }
  });
};

现在,要使任何React组件粘性,我只需添加到类中:
componentDidMount() {
  StickyAdapter.makeItSticky(this, ".some-other-div-which-is-the-container");
}

最后,粘性类的 CSS 样式如下:
.stick-to-top {
  display: block;
  position: sticky;
  top: 0;
  z-index: 10;
}

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