【问题标题】:How can I make a div stick to the top of the screen once it's been scrolled to?滚动到屏幕顶部后,如何使 div 贴在屏幕顶部?
【发布时间】:2010-11-16 00:16:29
【问题描述】:

我想创建一个 div,它位于内容块下方,但一旦页面滚动到足以接触其顶部边界,它就会固定到位并随页面滚动。

【问题讨论】:

  • 截至 2014 年 6 月,Sticky-kit jQuery plugin 是最简单的选择之一,提供了极低的进入门槛和许多功能。如果您正在寻找一种快速起步的简单方法,则可以从这里开始。
  • 添加 CSS position: sticky; top:0; 在 2017 年 1 月适用于大多数浏览器。
  • 天哪,position: sticky; 的东西太神奇了。
  • 可能是因为显示弯曲,请阅读:stackoverflow.com/a/66966273/5361964

标签: javascript jquery css scroll positioning


【解决方案1】:

您可以简单地使用 css,将您的元素定位为 fixed

.fixedElement {
    background-color: #c0c0c0;
    position:fixed;
    top:0;
    width:100%;
    z-index:100;
}

编辑:你应该有绝对位置的元素,一旦滚动偏移到达元素,它应该被改为固定,顶部位置应该设置为零。

您可以使用scrollTop 函数检测文档的顶部滚动偏移量:

$(window).scroll(function(e){ 
  var $el = $('.fixedElement'); 
  var isPositionFixed = ($el.css('position') == 'fixed');
  if ($(this).scrollTop() > 200 && !isPositionFixed){ 
    $el.css({'position': 'fixed', 'top': '0px'}); 
  }
  if ($(this).scrollTop() < 200 && isPositionFixed){
    $el.css({'position': 'static', 'top': '0px'}); 
  } 
});

当滚动偏移量达到 200 时,该元素将到浏览器窗口的顶部,因为它是固定放置的。

【讨论】:

  • 那不符合我的目标。我希望元素从页面顶部下方 200 像素处开始(为其他内容留出空间),然后一旦用户向下滚动,就会固定在顶部。
  • 您的编辑现在确实满足了问题的需要,但是当页面再次滚动回顶部时您仍然遇到问题。您可以在到达元素 scrollTop 后将其存储在某处,并且当页面再次到达该位置时(向上滚动时)将 css 更改回默认值...可能最好使用 .toggleClass 执行此操作...
  • 这与使用时差不多,但是当窗口滚动回顶部时,我确实必须删除固定定位。 if ($(this).scrollTop() &lt; 200 &amp;&amp; $el.css('position') == 'fixed') { $('.fixedElement').css({'position': 'static', 'top': '0px'}); }
  • @DerrickPetzold 我把它放到了答案中,非常重要的东西:)
  • 您提供的new example 链接非常干净清晰,我什至看不到! -_-
【解决方案2】:

提供的用于回答其他问题的信息可能对您有所帮助,埃文:

Check if element is visible after scrolling

您基本上想要修改元素的样式以将其设置为仅在验证 document.body.scrollTop 值等于或大于元素的顶部之后。

【讨论】:

    【解决方案3】:

    您已经在 Google Code 的 issue page 和(仅最近)在 Stack Overflow 的编辑页面上看到了这个示例。

    当您向上滚动时,CMS 的答案不会恢复定位。这是从 Stack Overflow 无耻窃取的代码:

    function moveScroller() {
        var $anchor = $("#scroller-anchor");
        var $scroller = $('#scroller');
    
        var move = function() {
            var st = $(window).scrollTop();
            var ot = $anchor.offset().top;
            if(st > ot) {
                $scroller.css({
                    position: "fixed",
                    top: "0px"
                });
            } else {
                $scroller.css({
                    position: "relative",
                    top: ""
                });
            }
        };
        $(window).scroll(move);
        move();
    }
    
    <div id="sidebar" style="width:270px;"> 
      <div id="scroller-anchor"></div> 
      <div id="scroller" style="margin-top:10px; width:270px"> 
        Scroller Scroller Scroller
      </div>
    </div>
    
    <script type="text/javascript"> 
      $(function() {
        moveScroller();
      });
    </script> 
    

    还有一个简单的live demo

    position: sticky 是一种新生的、无脚本的替代方案,它在 Chrome、Firefox 和 Safari 中受支持。请参阅 article on HTML5RocksdemoMozilla docs

    【讨论】:

    • 出于某种原因,{scroll:false} 给了我一些问题(jQuery 1.6.2)。没有它似乎工作。 Fork 来自链接演示。知道它是否有目的吗?
    • 我在这方面遇到了很多麻烦,我这辈子都无法复制,我什至尝试复制现场演示但它不起作用。谁能链接到提供分步说明的教程?
    • 当我使用与演示 (1.3.2) 相同版本的 jQuery 时,这似乎工作得很好。在某些时候offset 必须停止接受对象作为输入api.jquery.com/offset。 @Eddie 您的修改对于当前的 jQuery 应该是安全的。
    • 你有什么理由不能用 var d = $("#sidebar").offset().top; 替换 var d = $("#scroller-anchor").offset().top; 并一起摆脱空的滚动锚 div 吗?这是我的fork,展示了我在说什么。
    • @MikeDeck 我怀疑如果有边距或填充,您希望能够控制滚动条相对于容器的位置。
    【解决方案4】:

    接受的答案有效,但如果您在其上方滚动,它不会移回先前的位置。放在上面后总是粘在上面。

      $(window).scroll(function(e) {
        $el = $('.fixedElement');
        if ($(this).scrollTop() > 42 && $el.css('position') != 'fixed') {
          $('.fixedElement').css( 'position': 'fixed', 'top': '0px');
    
        } else if ($(this).scrollTop() < 42 && $el.css('position') != 'relative') {
          $('.fixedElement').css( 'relative': 'fixed', 'top': '42px');
    //this was just my previous position/formating
        }
      });
    

    jleedev 的回应应该有效,但我无法让它发挥作用。他的示例页面也不起作用(对我来说)。

    【讨论】:

      【解决方案5】:

      您可以添加 3 额外的行,这样当用户滚动回顶部时,div 将停留在原来的位置:

      代码如下:

      if ($(this).scrollTop() < 200 && $el.css('position') == 'fixed'){
          $('.fixedElement').css({'position': 'relative', 'top': '200px'});
      }
      

      【讨论】:

        【解决方案6】:

        我在 div 中设置了链接,因此它是字母和数字链接的垂直列表。

        #links {
            float:left;
            font-size:9pt;
            margin-left:0.5em;
            margin-right:1em;
            position:fixed;
            text-align:center;
            width:0.8em;
        }
        

        然后我设置了这个方便的 jQuery 函数来保存加载的位置,然后在滚动超出该位置时将位置更改为固定。

        注意:这仅适用于页面加载时链接可见的情况!

        var listposition=false;
        jQuery(function(){
             try{
                ///// stick the list links to top of page when scrolling
                listposition = jQuery('#links').css({'position': 'static', 'top': '0px'}).position();
                console.log(listposition);
                $(window).scroll(function(e){
                    $top = $(this).scrollTop();
                    $el = jQuery('#links');
                    //if(typeof(console)!='undefined'){
                    //    console.log(listposition.top,$top);
                    //}
                    if ($top > listposition.top && $el.css('position') != 'fixed'){
                        $el.css({'position': 'fixed', 'top': '0px'});
                    }
                    else if ($top < listposition.top && $el.css('position') == 'fixed'){
                        $el.css({'position': 'static'});
                    }
                });
        
            } catch(e) {
                alert('Please vendor admin@mydomain.com (Myvendor JavaScript Issue)');
            }
        });
        

        【讨论】:

          【解决方案7】:

          我遇到了和你一样的问题,最终制作了一个 jQuery 插件来解决它。它实际上解决了人们在此处列出的所有问题,此外还添加了一些可选功能。

          选项

          stickyPanelSettings = {
              // Use this to set the top margin of the detached panel.
              topPadding: 0,
          
              // This class is applied when the panel detaches.
              afterDetachCSSClass: "",
          
              // When set to true the space where the panel was is kept open.
              savePanelSpace: false,
          
              // Event fires when panel is detached
              // function(detachedPanel, panelSpacer){....}
              onDetached: null,
          
              // Event fires when panel is reattached
              // function(detachedPanel){....}
              onReAttached: null,
          
              // Set this using any valid jquery selector to 
              // set the parent of the sticky panel.
              // If set to null then the window object will be used.
              parentSelector: null
          };
          

          https://github.com/donnyv/sticky-panel

          演示: http://htmlpreview.github.io/?https://github.com/donnyv/sticky-panel/blob/master/jquery.stickyPanel/Main.htm

          【讨论】:

          • 嘿!谢谢!这是一个很好的解决方案,感谢分享,它确实为我节省了很多时间。这应该是这个问题的整体公认解决方案,因为据我所知,它是最完整的解决方案。基本上,其他的并没有解决 position: fixed 样式后一个块的原始 X 位置的问题。你的解决了这个问题。真的,非常感谢!
          • 嘿,Donny,也喜欢你的插件(v1.4.1)...确实遇到了一个问题,如果没有指定块元素,则会失去宽度。因此,在分离时对其进行了更改……仅通过设置宽度使其保持不变。 code// 分离面板 node.css({ "margin": 0, "left": nodeLeft, "top": newNodeTop, "position": "fixed", "width": node.width() }); code
          • 寻找并尝试了许多解决方案,并且“开箱即用”。惊人的工作!谢谢!
          • @WillHancock 我添加了 iPad 支持,修复了刷新错误并添加了 onDetached 和 onReattached 事件。新事件将允许您在面板和间隔面板分离和重新连接后访问它。
          • 还添加了 parentSelector 选项以支持滚动 div。
          【解决方案8】:

          我的解决方案有点冗长,但它可以处理从左边缘开始的可变定位以实现居中布局。

          // Ensurs that a element (usually a div) stays on the screen
          //   aElementToStick   = The jQuery selector for the element to keep visible
          global.makeSticky = function (aElementToStick) {
              var $elementToStick = $(aElementToStick);
              var top = $elementToStick.offset().top;
              var origPosition = $elementToStick.css('position');
          
              function positionFloater(a$Win) {
                  // Set the original position to allow the browser to adjust the horizontal position
                  $elementToStick.css('position', origPosition);
          
                  // Test how far down the page is scrolled
                  var scrollTop = a$Win.scrollTop();
                  // If the page is scrolled passed the top of the element make it stick to the top of the screen
                  if (top < scrollTop) {
                      // Get the horizontal position
                      var left = $elementToStick.offset().left;
                      // Set the positioning as fixed to hold it's position
                      $elementToStick.css('position', 'fixed');
                      // Reuse the horizontal positioning
                      $elementToStick.css('left', left);
                      // Hold the element at the top of the screen
                      $elementToStick.css('top', 0);
                  }
              }
          
              // Perform initial positioning
              positionFloater($(window));
          
              // Reposition when the window resizes
              $(window).resize(function (e) {
                  positionFloater($(this));
              });
          
              // Reposition when the window scrolls
              $(window).scroll(function (e) {
                  positionFloater($(this));
              });
          };
          

          【讨论】:

            【解决方案9】:

            我使用上面的一些工作来创建这项技术。我对其进行了一些改进,并认为我会分享我的工作。希望这会有所帮助。

            jsfiddle Code

            function scrollErrorMessageToTop() {
                var flash_error = jQuery('#flash_error');
                var flash_position = flash_error.position();
            
                function lockErrorMessageToTop() {
                    var place_holder = jQuery("#place_holder");
                    if (jQuery(this).scrollTop() > flash_position.top && flash_error.attr("position") != "fixed") {
                        flash_error.css({
                            'position': 'fixed',
                            'top': "0px",
                            "width": flash_error.width(),
                            "z-index": "1"
                        });
                        place_holder.css("display", "");
                    } else {
                        flash_error.css('position', '');
                        place_holder.css("display", "none");
                    }
            
                }
                if (flash_error.length > 0) {
                    lockErrorMessageToTop();
            
                    jQuery("#flash_error").after(jQuery("<div id='place_holder'>"));
                    var place_holder = jQuery("#place_holder");
                    place_holder.css({
                        "height": flash_error.height(),
                        "display": "none"
                    });
                    jQuery(window).scroll(function(e) {
                        lockErrorMessageToTop();
                    });
                }
            }
            scrollErrorMessageToTop();​
            

            这是一种更动态的滚动方式。它确实需要一些工作,我会在某个时候把它变成一个插件,但这是我在工作一个小时后想出的。

            【讨论】:

              【解决方案10】:

              这就是我使用 jquery 的方式。这一切都是从堆栈溢出的各种答案拼凑而成的。此解决方案缓存选择器以获得更快的性能,并且还解决了粘性 div 变得粘性时的“跳跃”问题。

              在 jsfiddle 上查看:http://jsfiddle.net/HQS8s/

              CSS:

              .stick {
                  position: fixed;
                  top: 0;
              }
              

              JS:

              $(document).ready(function() {
                  // Cache selectors for faster performance.
                  var $window = $(window),
                      $mainMenuBar = $('#mainMenuBar'),
                      $mainMenuBarAnchor = $('#mainMenuBarAnchor');
              
                  // Run this on scroll events.
                  $window.scroll(function() {
                      var window_top = $window.scrollTop();
                      var div_top = $mainMenuBarAnchor.offset().top;
                      if (window_top > div_top) {
                          // Make the div sticky.
                          $mainMenuBar.addClass('stick');
                          $mainMenuBarAnchor.height($mainMenuBar.height());
                      }
                      else {
                          // Unstick the div.
                          $mainMenuBar.removeClass('stick');
                          $mainMenuBarAnchor.height(0);
                      }
                  });
              });
              

              【讨论】:

                【解决方案11】:

                在javascript中你可以这样做:

                var element = document.getElementById("myid");
                element.style.position = "fixed";
                element.style.top = "0%";
                

                【讨论】:

                  【解决方案12】:

                  这就是 没有 jquery 的方法(更新:查看其他答案,您现在可以只使用 CSS)

                  var startProductBarPos=-1;
                  window.onscroll=function(){
                    var bar = document.getElementById('nav');
                    if(startProductBarPos<0)startProductBarPos=findPosY(bar);
                  
                    if(pageYOffset>startProductBarPos){
                      bar.style.position='fixed';
                      bar.style.top=0;
                    }else{
                      bar.style.position='relative';
                    }
                  
                  };
                  
                  function findPosY(obj) {
                    var curtop = 0;
                    if (typeof (obj.offsetParent) != 'undefined' && obj.offsetParent) {
                      while (obj.offsetParent) {
                        curtop += obj.offsetTop;
                        obj = obj.offsetParent;
                      }
                      curtop += obj.offsetTop;
                    }
                    else if (obj.y)
                      curtop += obj.y;
                    return curtop;
                  }
                  * {margin:0;padding:0;}
                  .nav {
                    border: 1px red dashed;
                    background: #00ffff;
                    text-align:center;
                    padding: 21px 0;
                  
                    margin: 0 auto;
                    z-index:10; 
                    width:100%;
                    left:0;
                    right:0;
                  }
                  
                  .header {
                    text-align:center;
                    padding: 65px 0;
                    border: 1px red dashed;
                  }
                  
                  .content {
                    padding: 500px 0;
                    text-align:center;
                    border: 1px red dashed;
                  }
                  .footer {
                    padding: 100px 0;
                    text-align:center;
                    background: #777;
                    border: 1px red dashed;
                  }
                  <header class="header">This is a Header</header>
                  <div id="nav" class="nav">Main Navigation</div>
                  <div class="content">Hello World!</div>
                  <footer class="footer">This is a Footer</footer>

                  【讨论】:

                  • 谢谢!这些天很难找到原生 JS 解决方案。这非常有效。
                  • 非常感谢,因为 jquery 与我的项目中的一些遗留企业代码冲突,所以这非常有效
                  • 虽然我遇到了一个问题,如果我滚动到页面底部,它会自动将我弹回顶部。
                  • @sng 我的示例页面会这样做吗?
                  • @JimW 我发现了这个问题。我试图将它与左侧主要内容 div 旁边的基于垂直的菜单栏一起使用。当您向下滚动时,它会出错,因为它无法确定它何时正确到达页面底部。我最终添加了一行代码来将容器 div 高度设置为滚动事件侦听器的窗口屏幕大小
                  【解决方案13】:

                  这里还有一个版本可供那些与其他版本有问题的人尝试。它汇集了this duplicate question 中讨论的技术,并动态生成所需的辅助 DIV,因此不需要额外的 HTML。

                  CSS:

                  .sticky { position:fixed; top:0; }
                  

                  JQuery:

                  function make_sticky(id) {
                      var e = $(id);
                      var w = $(window);
                      $('<div/>').insertBefore(id);
                      $('<div/>').hide().css('height',e.outerHeight()).insertAfter(id);
                      var n = e.next();
                      var p = e.prev();
                      function sticky_relocate() {
                        var window_top = w.scrollTop();
                        var div_top = p.offset().top;
                        if (window_top > div_top) {
                          e.addClass('sticky');
                          n.show();
                        } else {
                          e.removeClass('sticky');
                          n.hide();
                        }
                      }
                      w.scroll(sticky_relocate);
                      sticky_relocate();
                  }
                  

                  要使元素具有粘性,请执行以下操作:

                  make_sticky('#sticky-elem-id');
                  

                  当元素变得粘滞时,代码会管理剩余内容的位置,以防止它跳入粘滞元素留下的间隙。当滚动回其上方时,它还会将粘性元素返回到其原始的非粘性位置。

                  【讨论】:

                  • 您的方法与JohnB's approach 非常相似。考虑到您对该答案的差异,我想知道(1)使用第二个“助手 div”(而不是像 JohnB 使用的只有 1 个)是否有优势,以及(2)使用 hide() 和show() 而不是仅仅设置辅助 div 的高度(像 JohnB 那样)?也许是性能差异?到目前为止,我还无法辨别差异,但也许某些场景会有差异(比如可能涉及内联元素或其他东西),所以这就是我问的原因。谢谢。
                  【解决方案14】:

                  不是一个精确的解决方案,而是一个很好的替代方案

                  这个CSS ONLY Top of screen scroll bar。用 ONLY CSSNO JavaScript、NO JQuery、No 脑力劳动解决了所有问题(lol )。

                  享受my fiddle :D 所有代码都包含在其中:)

                  CSS

                  #menu {
                  position: fixed;
                  height: 60px;
                  width: 100%;
                  top: 0;
                  left: 0;
                  border-top: 5px solid #a1cb2f;
                  background: #fff;
                  -moz-box-shadow: 0 2px 3px 0px rgba(0, 0, 0, 0.16);
                  -webkit-box-shadow: 0 2px 3px 0px rgba(0, 0, 0, 0.16);
                  box-shadow: 0 2px 3px 0px rgba(0, 0, 0, 0.16);
                  z-index: 999999;
                  }
                  
                  .w {
                      width: 900px;
                      margin: 0 auto;
                      margin-bottom: 40px;
                  }<br type="_moz">
                  

                  把内容放得足够长,这样你就可以在这里看到效果了:) 哦,参考资料也在里面,因为他值得his credit

                  CSS ONLY Top of screen scroll bar

                  【讨论】:

                  • 有点离题 ;)
                  • 我并不反对一个好的解决方案,但您答案中的代码提供了一种方法,可以让菜单之类的东西始终保持在顶部。但这不是问题......
                  • 您只是在修复 div,并没有在滚动时做任何粘滞操作。
                  • 正如其他人指出的那样,这不会使元素在滚动时保持粘性,它只是始终固定在屏幕顶部,这当然可以在 css 中轻松完成。需要解决的是确定滚动量然后改变位置的过程:absolute -> fixed 并再次移除它
                  【解决方案15】:

                  这是另一种选择:

                  JAVASCRIPT

                  var initTopPosition= $('#myElementToStick').offset().top;   
                  $(window).scroll(function(){
                      if($(window).scrollTop() > initTopPosition)
                          $('#myElementToStick').css({'position':'fixed','top':'0px'});
                      else
                          $('#myElementToStick').css({'position':'absolute','top':initTopPosition+'px'});
                  });
                  

                  您的#myElementToStick 应以position:absolute CSS 属性开头。

                  【讨论】:

                  • 我认为这是一个非常干净和简单的解决方案。我只是不会将元素定位为“绝对”——这可能会破坏布局——我只会将其设置为静态。
                  【解决方案16】:

                  这是 Josh Lee 答案的扩展版本。如果您希望 div 在右侧的侧边栏上,并在一个范围内浮动(即,您需要指定顶部和底部锚点位置)。它还修复了您在移动设备上查看时的错误(您需要检查左滚动位置,否则 div 将移出屏幕)。

                  function moveScroller() {
                      var move = function() {
                          var st = $(window).scrollTop();
                          var sl = $(window).scrollLeft();
                          var ot = $("#scroller-anchor-top").offset().top;
                          var ol = $("#scroller-anchor-top").offset().left;
                          var bt = $("#scroller-anchor-bottom").offset().top;
                          var s = $("#scroller");
                          if(st > ot) {
                              if (st < bt - 280) //280px is the approx. height for the sticky div
                              {
                                  s.css({
                                      position: "fixed",
                                      top: "0px",
                                      left: ol-sl
                                  }); 
                              }
                              else
                              {
                                  s.css({
                                      position: "fixed",
                                      top: bt-st-280,
                                      left: ol-sl
                                  }); 
                              }
                          } else {
                              s.css({
                                  position: "relative",
                                  top: "",
                                  left: ""
                              });
                  
                          }
                      };
                      $(window).scroll(move);
                      move();
                  }
                  

                  【讨论】:

                    【解决方案17】:

                    这是一个使用 jquery-visible 插件的示例:http://jsfiddle.net/711p4em4/

                    HTML:

                    <div class = "wrapper">
                        <header>Header</header>
                        <main>
                            <nav>Stick to top</nav>
                            Content
                        </main>
                        <footer>Footer</footer>
                    </div>
                    

                    CSS:

                    * {
                        margin: 0;
                        padding: 0;
                    }
                    
                    body {
                        background-color: #e2e2e2;
                    }
                    
                    .wrapper > header,
                    .wrapper > footer {
                        font: 20px/2 Sans-Serif;
                        text-align: center;
                        background-color: #0040FF;
                        color: #fff;
                    }
                    
                    .wrapper > main {
                        position: relative;
                        height: 500px;
                        background-color: #5e5e5e;
                        font: 20px/500px Sans-Serif;
                        color: #fff;
                        text-align: center;
                        padding-top: 40px;
                    }
                    
                    .wrapper > main > nav {
                        position: absolute;
                        top: 0;
                        left: 0;
                        right: 0;
                        font: 20px/2 Sans-Serif;
                        color: #fff;
                        text-align: center;
                        background-color: #FFBF00;
                    }
                    
                    .wrapper > main > nav.fixed {
                        position: fixed;
                        top: 0;
                        left: 0;
                        right: 0;
                    }
                    

                    JS(包括 jquery-visible 插件):

                    (function($){
                    
                        /**
                         * Copyright 2012, Digital Fusion
                         * Licensed under the MIT license.
                         * http://teamdf.com/jquery-plugins/license/
                         *
                         * @author Sam Sehnert
                         * @desc A small plugin that checks whether elements are within
                         *       the user visible viewport of a web browser.
                         *       only accounts for vertical position, not horizontal.
                         */
                        var $w = $(window);
                        $.fn.visible = function(partial,hidden,direction){
                    
                            if (this.length < 1)
                                return;
                    
                            var $t        = this.length > 1 ? this.eq(0) : this,
                                t         = $t.get(0),
                                vpWidth   = $w.width(),
                                vpHeight  = $w.height(),
                                direction = (direction) ? direction : 'both',
                                clientSize = hidden === true ? t.offsetWidth * t.offsetHeight : true;
                    
                            if (typeof t.getBoundingClientRect === 'function'){
                    
                                // Use this native browser method, if available.
                                var rec = t.getBoundingClientRect(),
                                    tViz = rec.top    >= 0 && rec.top    <  vpHeight,
                                    bViz = rec.bottom >  0 && rec.bottom <= vpHeight,
                                    lViz = rec.left   >= 0 && rec.left   <  vpWidth,
                                    rViz = rec.right  >  0 && rec.right  <= vpWidth,
                                    vVisible   = partial ? tViz || bViz : tViz && bViz,
                                    hVisible   = partial ? lViz || rViz : lViz && rViz;
                    
                                if(direction === 'both')
                                    return clientSize && vVisible && hVisible;
                                else if(direction === 'vertical')
                                    return clientSize && vVisible;
                                else if(direction === 'horizontal')
                                    return clientSize && hVisible;
                            } else {
                    
                                var viewTop         = $w.scrollTop(),
                                    viewBottom      = viewTop + vpHeight,
                                    viewLeft        = $w.scrollLeft(),
                                    viewRight       = viewLeft + vpWidth,
                                    offset          = $t.offset(),
                                    _top            = offset.top,
                                    _bottom         = _top + $t.height(),
                                    _left           = offset.left,
                                    _right          = _left + $t.width(),
                                    compareTop      = partial === true ? _bottom : _top,
                                    compareBottom   = partial === true ? _top : _bottom,
                                    compareLeft     = partial === true ? _right : _left,
                                    compareRight    = partial === true ? _left : _right;
                    
                                if(direction === 'both')
                                    return !!clientSize && ((compareBottom <= viewBottom) && (compareTop >= viewTop)) && ((compareRight <= viewRight) && (compareLeft >= viewLeft));
                                else if(direction === 'vertical')
                                    return !!clientSize && ((compareBottom <= viewBottom) && (compareTop >= viewTop));
                                else if(direction === 'horizontal')
                                    return !!clientSize && ((compareRight <= viewRight) && (compareLeft >= viewLeft));
                            }
                        };
                    
                    })(jQuery);
                    
                    $(function() {
                        $(window).scroll(function() {
                            $(".wrapper > header").visible(true) ?
                                $(".wrapper > main > nav").removeClass("fixed") :
                                $(".wrapper > main > nav").addClass("fixed");
                        });
                    });
                    

                    【讨论】:

                      【解决方案18】:

                      我在搜索相同内容时遇到了这个问题。我知道这是一个老问题,但我想我会提供一个更新的答案。

                      Scrollorama 有一个“固定”功能,这正是我想要的。

                      http://johnpolacek.github.io/scrollorama/

                      【讨论】:

                        【解决方案19】:

                        直到页脚到达 div 为止:

                        function stickyCostSummary() {
                            var stickySummary = $('.sticky-cost-summary');
                            var scrollCostSummaryDivPosition = $(window).scrollTop();
                            var footerHeight = $('#footer').height();
                            var documentHeight = $(document).height();
                            var costSummaryHeight = stickySummary.height();
                            var headerHeight = 83;
                            var footerMargin = 10;
                            var scrollHeight = 252;
                            var footerPosition = $('#footer').offset().top;
                        
                            if (scrollCostSummaryDivPosition > scrollHeight && scrollCostSummaryDivPosition <= (documentHeight - footerHeight - costSummaryHeight - headerHeight - footerMargin)) {
                                stickySummary.removeAttr('style');
                                stickySummary.addClass('fixed');
                        
                            } else if (scrollCostSummaryDivPosition > (documentHeight - footerHeight - costSummaryHeight - headerHeight - footerMargin)) {
                                stickySummary.removeClass('fixed');
                                stickySummary.css({
                                  "position" : "absolute",
                                  "top" : (documentHeight - footerHeight - costSummaryHeight - headerHeight - footerMargin - scrollHeight) + "px"
                              });
                            } else {
                                stickySummary.removeClass('fixed');
                                stickySummary.css({
                                    "position" : "absolute",
                                    "top" : "0"
                                });
                            }
                        }
                        
                        $window.scroll(stickyCostSummary);
                        

                        【讨论】:

                          【解决方案20】:

                          自 2017 年 1 月和 Chrome 56 发布以来,大多数常用浏览器都支持 CSS 中的 position: sticky 属性。

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

                          在 Firefox 和 Chrome 中对我有用。

                          在 Safari 中你仍然需要使用position: -webkit-sticky

                          Polyfills 可用于 Internet Explorer 和 Edge; https://github.com/wilddeer/stickyfill 好像不错。

                          【讨论】:

                          • 当今大多数常用浏览器都支持此功能。请参阅 caniuse.com/#feat=css-sticky 其次,我更喜欢可以将 2 行代码归结为需要自定义 Javascript 的版本的解决方案。它也是面向未来的。如果您担心浏览器兼容性,请使用 polyfill。
                          • 我想在这个评论中补充一点,我们可以 z-index: 99999;,因为如果不是当它到达顶部时,其他内容将首先呈现。但这应该是公认的解决方案。
                          • 只需将其包装在 id="thing_to_stick" 的 div 中
                          • px 部分对我不起作用,让我觉得sticky 不起作用。它应该只是top: 0;
                          【解决方案21】:

                          正如Josh LeeColin 't Hart 所说,您可以选择只使用position: sticky; top: 0; 应用于您希望滚动的div...

                          另外,您唯一需要做的就是将其复制到页面顶部或格式化以适合外部 CSS 表:

                          <style>
                          #sticky_div's_name_here { position: sticky; top: 0; }
                          </style>
                          

                          只需将 #sticky_div's_name_here 替换为您的 div 的名称,即如果您的 div 是 &lt;div id="example"&gt;,您将输入 #example { position: sticky; top: 0; }

                          【讨论】:

                            【解决方案22】:

                            最简单的解决方案(不带js): demo

                            .container {
                              position: relative;
                            }
                            .sticky-div {
                                position: sticky;
                                top: 0;
                            }
                            
                            <div class="container">
                              <h1>
                                relative container & sticky div
                              </h1>
                              <div class="sticky-div"> this row is sticky</div>
                              <div>
                                content
                              </div>
                            </div>
                            

                            【讨论】:

                              猜你喜欢
                              • 1970-01-01
                              • 1970-01-01
                              • 1970-01-01
                              • 1970-01-01
                              • 1970-01-01
                              • 1970-01-01
                              • 1970-01-01
                              • 2020-12-13
                              相关资源
                              最近更新 更多