【问题标题】:Set sidebar height equal with content on scroll设置侧边栏高度等于滚动内容
【发布时间】:2017-07-14 16:26:45
【问题描述】:

有时我的内容 div 的高度大于侧边栏的高度,而且它不好看。

如果内容高度大于侧边栏,我想这样做,在页面滚动时将边距顶部添加到侧边栏直到内容底部

我试图用这段代码做到这一点:

var sidebar = $("#sidebar").outerHeight();
var content = $("#content-left").outerHeight();
var gap = (content - sidebar);
$(window).scroll(function() {
if ($(this).scrollTop() > gap) { 
if (content > sidebar ) {
$("#sidebar").css('margin-top', +gap);
}}}); 

但这实际上并不是我想要做的。如果用户滚动 20px,我希望在内容底部添加 20px 边距。

如果有更简单更好的方法,请告诉我。

感谢您的帮助!

更新:

这是我的#content-left css:#content-left { float: left;width: 68%;}

和#sidebar css:

float: right;
width: 30%;
height: auto;
padding: 0;
margin-top: 0px;
margin-bottom: 15px;
overflow: hidden;

【问题讨论】:

    标签: jquery css


    【解决方案1】:

    我决定改进答案(在被接受后)。现在我创建了一个函数,它将处理 div 的定位。您可以在滚动、调整窗口大小等时运行它。我认为如果有人想使用此代码,这将非常有用。

    只需更改变量:

    • 内容高度
    • 侧边栏高度
    • 内容偏移

    你已经完成了:)。

    欢迎提出进一步改进的建议。

    JS-小提琴

    JS-Fiddle

    html

    <header>
    <h1>"The sticking sidebar"</h1>
    </header>
    <div id="content"><p>START<br/> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus a tellus tincidunt, lacinia ex facilisis, facilisis ipsum. Pellentesque ac accumsan mi. Vestibulum iaculis luctus ultricies. Integer aliquet, felis id facilisis consectetur, tortor ligula eleifend urna, convallis facilisis erat erat nec libero. Pellentesque finibus sed leo vel tincidunt. Praesent in est erat. Donec nec varius leo. Nam convallis feugiat velit at commodo. Mauris feugiat lorem eros, a varius sem gravida eu. Ut convallis, velit hendrerit semper laoreet, libero nunc egestas neque, et ultrices ex elit et lacus.</p><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus a tellus tincidunt, lacinia ex facilisis, facilisis ipsum. Pellentesque ac accumsan mi. Vestibulum iaculis luctus ultricies. Integer aliquet, felis id facilisis consectetur, tortor ligula eleifend urna, convallis facilisis erat erat nec libero. Pellentesque finibus sed leo vel tincidunt. Praesent in est erat. Donec nec varius leo. Nam convallis feugiat velit at commodo. Mauris feugiat lorem eros, a varius sem gravida eu. Ut convallis, velit hendrerit semper laoreet, libero nunc egestas neque, et ultrices ex elit et lacus.</p><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus a tellus tincidunt, lacinia ex facilisis, facilisis ipsum. Pellentesque ac accumsan mi. Vestibulum iaculis luctus ultricies. Integer aliquet, felis id facilisis consectetur, tortor ligula eleifend urna, convallis facilisis erat erat nec libero. Pellentesque finibus sed leo vel tincidunt. Praesent in est erat. Donec nec varius leo. Nam convallis feugiat velit at commodo. Mauris feugiat lorem eros, a varius sem gravida eu. Ut convallis, velit hendrerit semper laoreet, libero nunc egestas neque, et ultrices ex elit et lacus.</p><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus a tellus tincidunt, lacinia ex facilisis, facilisis ipsum. Pellentesque ac accumsan mi. Vestibulum iaculis luctus ultricies. Integer aliquet, felis id facilisis consectetur, tortor ligula eleifend urna, convallis facilisis erat erat nec libero. Pellentesque finibus sed leo vel tincidunt. Praesent in est erat. Donec nec varius leo. Nam convallis feugiat velit at commodo. Mauris feugiat lorem eros, a varius sem gravida eu. Ut convallis, velit hendrerit semper laoreet, libero nunc egestas neque, et ultrices ex elit et lacus.<br/>END</p></div>
    <div id="sidebar"><p>START<br/> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus a tellus tincidunt, lacinia ex facilisis, facilisis ipsum. Pellentesque ac accumsan mi. Vestibulum iaculis luctus ultricies. Integer aliquet, felis id facilisis consectetur, tortor ligula eleifend urna, convallis facilisis erat erat nec libero. Pellentesque finibus sed leo vel tincidunt. Praesent in est erat. Donec nec varius leo. Nam convallis feugiat velit at commodo. Mauris feugiat lorem eros, a varius sem gravida eu. Ut convallis, velit hendrerit semper laoreet, libero nunc egestas neque, et ultrices ex elit et lacus.<br/>END</p></div>
    <footer><i>footer</i></footer>
    

    css

    header h1{
      text-align: center;
    }
    #content{
      float: left;
      width: 70%;
      background-color: rgb(150, 150, 0)
    }
    #sidebar{
      position: relative;
      width: 30%;
      float: right;
      background-color: yellow;
    }
    

    js/jQuery

      $(document).ready(function(){
      // define variables before scrollin to destress the processor
      let contentHeight = $("#content").height();
      let sidebarHeight = $("#sidebar").height();
      let windowHeight = $(window).height();
      let doc = $(document); 
      let contentOffset = $("#content").offset().top;
    
      $(window).resize(function(){
        //should reset all variables here or the code will bug out on screen resizing 
      contentHeight = $("#content").height();;
      sidebarHeight = $("#sidebar").height();
      windowHeight = $(window).height();
      contentOffset = $("#content").offset().top;
      determineSidebarScrollBehavior(doc, contentHeight, contentOffset, sidebarHeight,windowHeight);
      });
      $(document).scroll(function(){
                determineSidebarScrollBehavior(doc, contentHeight, contentOffset, sidebarHeight, windowHeight);
      }); // end scroll
    });//end ready
    
    function determineSidebarScrollBehavior(doc, contentHeight, contentOffset, sidebarHeight, windowHeight){ 
        //only run if the #sidebar is higher than the #content
      if(contentHeight>sidebarHeight){
        var scrollTop = doc.scrollTop();
        //check if variable has been previously created by this function else the value is 0
        let oldScrollTop = (window.oldScrollTop)?window.oldScrollTop:0;
        //create a marginTop var if it doesn t exist yet
        window.marginTop = (window.marginTop)?marginTop:0;
        //determine if you scroll up op down
        let isScrollingDown = (scrollTop>oldScrollTop)?true:false;
        //if the end of the sidebar reaches the end of the window change margin so it "sticks". It should stick until the #sidebar reaches the same height (inculding margin) as the #content.
        if(isScrollingDown && scrollTop+windowHeight > contentOffset + sidebarHeight + marginTop){
        marginTop = scrollTop + windowHeight-sidebarHeight-contentOffset;
        // check if content would be too long, if so set the maximum marginTop
        if(marginTop>contentHeight-sidebarHeight){
            marginTop = contentHeight-sidebarHeight;
          }
        }    
        // if the start of the sidebar reaches the top while scrolling up, make it "stick"
            else if(!isScrollingDown && scrollTop < contentOffset + marginTop){
            marginTop = scrollTop - contentOffset;
          // make sure margin-top cannot go negative
          if(marginTop<0){
            marginTop = 0;
          }
        }
        //change the margin
        $("#sidebar").css({'margin-top': marginTop});
      }
      window.oldScrollTop = scrollTop;
    }
    

    【讨论】:

    • 非常感谢,您的代码运行良好,但仍有一些问题需要解决。我用你的代码录制了一个视频。 Please watch from here 。只有当用户看到侧边栏的末尾时,我们才需要添加 margin-top。正如您在视频中看到的,当滚动回顶部时,侧边栏看起来不太好。仍然有利润顶部。我希望我能解释一下。再次感谢您的帮助:) @RMo
    • jsfiddle.net/uzfxg6zz/7 这有点工作,但是..这可能会更好。我注意到您的视频中有一些严重的延迟,因此希望由于一些额外的优化,它的延迟会减少一点。如果它运作良好,请发表评论,我会将其更新为我的答案。
    • 这项工作量很大,非常感谢您的帮助。现在,它工作得很好而且更好。我再次录制了video,我认为有两件事需要解决。首先,在 7. 第二,正如您在内容底部看到的那样,侧边栏边距被删除。它还能粘到内容的底部吗?再次在 9. 秒,侧边栏在向下滚动时会粘住。我们可以在滚动顶部时粘贴侧边栏的顶部而不是底部吗?它可以以粘性的方式一直到内容的顶部吗?再次感谢您
    • 看起来我忘记了条件中的 contentOffset。这看起来更好:jsfiddle.net/uzfxg6zz/8。至于向上滚动。我认为这是可能的,但你必须检测你是向上还是向下滚动,然后从那里开始。
    • 非常感谢@RMo,它真的很好用,我想你现在可以编辑你的答案了。感谢您的帮助。
    【解决方案2】:

    您可以使用 flex 并放弃 javascript。我在下面为你写了一个简单的例子。

    body {
      margin: 0;
      width: 100%;
      height: 100%;
    }
    
    .container {
      display: flex;
    }
    
    .sidebar {
      min-height: 100vh;
      width: 20%;
      background: pink;
    }
    
    .content {
      min-height: 100vh;
      width: 80%;
      background: blue;
    }
    <div class="container">
      <div class="sidebar"></div>
      <div class="content"></div>
    </div>

    【讨论】:

    • 感谢您的回答,但我在侧边栏和内容中有 div,如果我将 display:flex 添加到内容,所有 div 都会像 this 一样混乱。我已经在网上查看了其他解决方案,但没有一个对我有用。我认为唯一的方法是使用 margin-top 来做到这一点:)
    • 您应该只将 flex 添加到容器中,而不是内容容器本身。 @Solhan
    • 我添加了 display:flex;仅 #content-left div 。我做错了吗?
    • 是的,您能否提供一个更详细的示例,我可以为您解决这个问题。 @Solhan
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-28
    • 1970-01-01
    • 1970-01-01
    • 2012-12-29
    • 2012-05-26
    相关资源
    最近更新 更多