繁体   English   中英

如何在使用jQuery在页眉和页脚之间滚动时使侧边栏变粘(不滚动它们)?

[英]How to make a sidebar sticky when scrolling between header and footer with jQuery (without scrolling over them)?

我需要一个严格的jQuery解决方案来解决这个问题。 这是因为我正在使用Wordpress,而我想制作粘贴的侧边栏小部件位于<aside>元素内,我无法使其达到全高。

就像.scrollTop()检测页面向下移动侧边栏小部件的距离一样,我需要JS检测我从页面底部到目前为止通过分配新的固定位置来“取消”小部件。

我尝试使用.offset()进行此操作,但到目前为止我还无法使其工作。

  function stopDiv() {
    var distance = $('.footer').offset().top - $('.widget').offset().top;
    if (distance < 10) {
      $('.widget').css({
        'top': 'auto',
        'bottom': '10px'
      });
    }
  }

你可以在我的侧栏下方的片段中看到它应该滚动,但我希望侧边栏在距离页脚距离<10px时采用新的固定位置。

我希望侧边栏在页脚上方采用新的固定位置,直到用户向上滚动。

编辑: @Benvc下面建议的解决方案在片段中工作正常,但在我的wordpress网站上没有。 以下是我得到的控制台错误:

scripts.js:18 Uncaught ReferenceError: s is not defined
    at HTMLDocument.<anonymous> (scripts.js:18)
    at i (jquery.js:2)
    at Object.fireWith [as resolveWith] (jquery.js:2)
    at Function.ready (jquery.js:2)
    at HTMLDocument.K (jquery.js:2)
    at HTMLDocument.s (VM11874 rocket-loader.min.js:1)
    at p (VM11874 rocket-loader.min.js:1)
    at t.simulateStateAfterDeferScriptsActivation (VM11874 rocket-loader.min.js:1)
    at Object.callback (VM11874 rocket-loader.min.js:1)
    at t.run (VM11874 rocket-loader.min.js:1)

  // Fixed Widget function fixDiv() { var $cache = $('.widget'); if ($(window).scrollTop() > 380) $cache.css({ 'position': 'fixed', 'top': '10px', 'right': '30px' }); else $cache.css({ 'position': 'relative', 'top': 'auto', 'right': 'auto' }); } $(window).scroll(fixDiv); fixDiv(); /* My attempt function stopDiv() { var distance = $('.footer').offset().top - $('.widget').offset().top; if (distance < 10) { $('.widget').css({ 'top': 'auto', 'bottom': '10px' }); } } $(window).scroll(stopDiv); stopDiv(); */ 
 @import url('https://fonts.googleapis.com/css?family=Open+Sans:400,700'); * { font-family: 'Open Sans'; color: #fff; box-sizing: content-box; } body { padding: 0; margin: 0; } p { margin: 20px; } hr { width: 85%; border-style: solid; } .main-content { width: 100%; display: grid; grid-template-columns: repeat(4, 1fr); grid-template-rows: 150px auto; grid-template-areas: "nav nav nav nav" "main main main sidebar"; grid-column-gap: 20px; grid-row-gap: 0px; } .nav { grid-area: nav; background-color: #266392; display: grid; grid-template-columns: 1fr 3fr 1fr; } .nav h1 { place-self: center; font-weight: 400; font-size: 40px; grid-column: 2; } .nav i { align-self: center; font-size: 40px; } .main { height: 1500px; width: 98%; justify-self: start; grid-area: main; padding: 10px; float: left; background-color: #e8624c; margin: 10px; } .sidebar-container { height: 900px; width: 300px; justify-self: start; background-color: #209B66; grid-area: sidebar; grid-column: 4; top: 10px; margin: 10px; padding: 20px; display: grid; grid-template-rows: auto; grid-row-gap: 10px; } .sidebar-container>p { display: grid; align-items: start; padding: 0; margin: 0; } .widget { height: 500px; width: 300px; background-color: #E3962F; } .footer { background-color: #333; height: 800px; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <body> <div class="main-content"> <div class="nav"> <h1>Sticky Sidebar Problem</h1> <i class="fa fa-arrow-down" aria-hidden="true"></i> </div> <div class="main"> <p> [Main Content] </p> </div> <div class="sidebar-container"> <p>[Sidebar Container]</p> <div class="widget"> <p> [Widget]</p> </div> </div> </div> <div class="footer"></div> </body> 

我们可以将其分解为两个不同的问题。 问题#1,您需要元素(a)的底部Y和弦,而问题#2需要页面底部(b)。 如果您有这些数据,那么您的答案就是(b - a)。

为了帮助我们,让我们创建一个辅助函数:

function getOffset(el) {
  const rect = el.getBoundingClientRect();
  return {
    left: rect.left + window.scrollX,
    right: rect.left - window.scrollX,
    top: rect.top + window.scrollY,
    bottom: rect.bottom -window.scrollY
  };
}

使用它,它应该像getOffset(document.body).bottom - getOffset(yourElement).bottom一样简单。

希望这可以帮助!

(请注意,我现在无法实际测试此代码,因此它可能无法开箱即用,因此请将其更多地用作指南而不是复制/粘贴)。

编辑 - jquery解决方案(原css只在下面回答):

基于你的问题编辑,提供额外的约束,并使一个html / css唯一的解决方案有点困难,下面是一个jquery解决方案使用你的代码与新的jquery粘粘侧边栏小部件和CSS使侧边栏小部件的position: absoluteright: 30px (该值是任意的,具体取决于您希望窗口小部件位于侧边right: 30px确切位置)。 此外,注释掉了一些其他css行,这些行或者没有做任何事情或者干扰了网格布局的响应性(粘性侧边栏功能可以使用或不使用这些更改,尽管您可能需要调整窗口小部件元素的right css,包括媒体查询,具体取决于您的布局最终结束的位置)。

 $(function() { const sidebar = $('.sidebar-container'); const widget = $('.widget'); const footer = $('.footer'); const space = 10; // arbitrary value to create space between the window and widget const startTop = sidebar.offset().top + 60; // arbitrary start top position const endTop = footer.offset().top - widget.height() - space; widget.css('top', startTop); $(window).scroll(function() { let windowTop = $(this).scrollTop(); let widgetTop = widget.offset().top; let newTop = startTop; if (widgetTop >= startTop && widgetTop <= endTop) { if (windowTop > startTop - space && windowTop < endTop - space) { newTop = windowTop + space; } else if (windowTop > endTop - space) { newTop = endTop; } widget.stop().animate({ 'top': newTop }); } }); }); 
 @import url('https://fonts.googleapis.com/css?family=Open+Sans:400,700'); * { font-family: 'Open Sans'; color: #fff; box-sizing: content-box; } body { padding: 0; margin: 0; } p { margin: 20px; } hr { width: 85%; border-style: solid; } .main-content { width: 100%; display: grid; grid-template-columns: repeat(4, 1fr); grid-template-rows: 150px auto; grid-template-areas: "nav nav nav nav" "main main main sidebar"; grid-column-gap: 20px; grid-row-gap: 0px; } .nav { grid-area: nav; background-color: #266392; display: grid; grid-template-columns: 1fr 3fr 1fr; } .nav h1 { place-self: center; font-weight: 400; font-size: 40px; grid-column: 2; } .nav i { align-self: center; font-size: 40px; } .main { height: 1500px; /*width: 98%; justify-self: start;*/ grid-area: main; padding: 10px; /*float: left;*/ background-color: #e8624c; margin: 10px; } .sidebar-container { height: 900px; width: 300px; justify-self: end; background-color: #209B66; grid-area: sidebar; grid-column: 4; /*top: 10px;*/ margin: 10px; padding: 20px; display: grid; grid-template-rows: auto; grid-row-gap: 10px; } .sidebar-container>p { display: grid; align-items: start; padding: 0; margin: 0; } .widget { height: 500px; width: 300px; background-color: #E3962F; position: absolute; right: 30px; } .footer { background-color: #333; height: 800px; } 
 <body> <div class="main-content"> <div class="nav"> <h1>Sticky Sidebar Problem</h1> <i class="fa fa-arrow-down" aria-hidden="true"></i> </div> <div class="main"> <p> [Main Content] </p> </div> <div class="sidebar-container"> <p>[Sidebar Container]</p> <div class="widget"> <p> [Widget]</p> </div> </div> </div> <div class="footer"></div> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> </body> 

ORIGINAL - css解决方案:

根据您对页脚和浏览器兼容性的要求,您可以获得所需的效果,而无需任何javascript / jquery。 您必须对您的html进行微调,将页脚移动到网格外并单独设置样式(我只是为下面的示例添加了高度)。 然后,你可以添加position: stickytop: 10px到你的.sidebar css。

结果是标题滚动后侧边栏开始滚动,然后当它碰到页脚时停止滚动。

请注意,IE中不支持position: sticky (有一个粘贴polyfill )。

通过示例调整代码,查看下面的代码段:

 body { padding: 0; margin: 0; } .main-content { width: 100%; display: grid; grid-template-columns: repeat(4, 1fr); grid-template-rows: 80px auto 400px; grid-template-areas: "nav nav nav nav" "main main main sidebar" "footer footer footer footer"; grid-column-gap: 20px; grid-row-gap: 10px; height: 100%; } .nav { grid-area: nav; background-color: #007ccc; } .main { height: 100%; max-width: 600px; justify-self: start; grid-area: main; padding: 10px; float: left; } .sidebar { height: 600px; width: 300px; justify-self: start; background-color: #4BA25E; grid-area: sidebar; grid-column: 4; margin: 10px; position: sticky; top: 10px; } .footer { background-color: #333; height: 400px; } 
 <body> <div class="main-content"> <div class="nav"></div> <div class="main"> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin tincidunt tempus nisi, vitae finibus nunc pharetra quis. Quisque in vehicula nunc. Nullam nec velit sed mi posuere ultricies pellentesque quis nibh. Morbi consequat, dui at consequat rhoncus, neque nulla posuere odio, non dapibus velit urna in turpis. In feugiat massa orci, vitae scelerisque sem posuere ut.</p> <p>Phasellus porttitor diam metus. Suspendisse quis mi sollicitudin, lobortis orci eu, pharetra ex. Cras ex nibh, dapibus quis tortor a, placerat commodo lorem. Mauris sed sapien ligula. Praesent lobortis cursus varius. Donec vulputate pulvinar interdum. Suspendisse laoreet malesuada commodo.</p> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin tincidunt tempus nisi, vitae finibus nunc pharetra quis. Quisque in vehicula nunc. Nullam nec velit sed mi posuere ultricies pellentesque quis nibh. Morbi consequat, dui at consequat rhoncus, neque nulla posuere odio, non dapibus velit urna in turpis. In feugiat massa orci, vitae scelerisque sem posuere ut.</p> <p>Phasellus porttitor diam metus. Suspendisse quis mi sollicitudin, lobortis orci eu, pharetra ex. Cras ex nibh, dapibus quis tortor a, placerat commodo lorem. Mauris sed sapien ligula. Praesent lobortis cursus varius. Donec vulputate pulvinar interdum. Suspendisse laoreet malesuada commodo.</p> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin tincidunt tempus nisi, vitae finibus nunc pharetra quis. Quisque in vehicula nunc. Nullam nec velit sed mi posuere ultricies pellentesque quis nibh. Morbi consequat, dui at consequat rhoncus, neque nulla posuere odio, non dapibus velit urna in turpis. In feugiat massa orci, vitae scelerisque sem posuere ut.</p> <p>Phasellus porttitor diam metus. Suspendisse quis mi sollicitudin, lobortis orci eu, pharetra ex. Cras ex nibh, dapibus quis tortor a, placerat commodo lorem. Mauris sed sapien ligula. Praesent lobortis cursus varius. Donec vulputate pulvinar interdum. Suspendisse laoreet malesuada commodo.</p> <p>In hac habitasse platea dictumst. Maecenas et mauris nunc. Aliquam erat volutpat. Duis eu condimentum ipsum. Etiam a mattis ipsum, sit amet vestibulum felis. In fermentum purus augue, vitae interdum ante gravida non. In tincidunt risus vitae ligula dignissim pellentesque. Vivamus id est eget metus placerat euismod et nec diam. Integer luctus bibendum condimentum.</p> <p>Vestibulum pretium quis mauris id pellentesque. Donec placerat iaculis ex, ut porta dolor vestibulum ac. Phasellus nunc tellus, viverra vestibulum posuere eu, faucibus vitae ex. Aenean efficitur maximus nunc, at sagittis nunc mattis sed. Vivamus et magna vitae magna interdum sodales. Ut imperdiet lobortis consectetur.</p> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin tincidunt tempus nisi, vitae finibus nunc pharetra quis. Quisque in vehicula nunc. Nullam nec velit sed mi posuere ultricies pellentesque quis nibh. Morbi consequat, dui at consequat rhoncus, neque nulla posuere odio, non dapibus velit urna in turpis. In feugiat massa orci, vitae scelerisque sem posuere ut.</p> <p>Phasellus porttitor diam metus. Suspendisse quis mi sollicitudin, lobortis orci eu, pharetra ex. Cras ex nibh, dapibus quis tortor a, placerat commodo lorem. Mauris sed sapien ligula. Praesent lobortis cursus varius. Donec vulputate pulvinar interdum. Suspendisse laoreet malesuada commodo.</p> <p>In hac habitasse platea dictumst. Maecenas et mauris nunc. Aliquam erat volutpat. Duis eu condimentum ipsum. Etiam a mattis ipsum, sit amet vestibulum felis. In fermentum purus augue, vitae interdum ante gravida non. In tincidunt risus vitae ligula dignissim pellentesque. Vivamus id est eget metus placerat euismod et nec diam. Integer luctus bibendum condimentum.</p> <p>Vestibulum pretium quis mauris id pellentesque. Donec placerat iaculis ex, ut porta dolor vestibulum ac. Phasellus nunc tellus, viverra vestibulum posuere eu, faucibus vitae ex. Aenean efficitur maximus nunc, at sagittis nunc mattis sed. Vivamus etmagna vitae magna interdum sodales. Ut imperdiet lobortis consectetur.</p> <p>Vestibulum pretium quis mauris id pellentesque. Donec placerat iaculis ex, ut porta dolor vestibulum ac. Phasellus nunc tellus, viverra vestibulum posuere eu, faucibus vitae ex. Aenean efficitur maximus nunc, at sagittis nunc mattis sed. Vivamus etmagna vitae magna interdum sodales. Ut imperdiet lobortis consectetur.</p> <p>Vestibulum pretium quis mauris id pellentesque. Donec placerat iaculis ex, ut porta dolor vestibulum ac. Phasellus nunc tellus, viverra vestibulum posuere eu, faucibus vitae ex. Aenean efficitur maximus nunc, at sagittis nunc mattis sed. Vivamus etmagna vitae magna interdum sodales. Ut imperdiet lobortis consectetur.</p> </div> <div class="sidebar"></div> </div> <div class="footer"></div> </body> 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM