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


当前回答

这里还有一个版本供那些对其他版本有问题的人尝试。它结合了这个重复问题中讨论的技术,并动态生成所需的帮助器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');

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

其他回答

粘到页脚碰到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);

这就是我用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);
        }
    });
});

这里是如何不使用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>

我和你有同样的问题,最终制作了一个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

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

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

在火狐和Chrome浏览器中都是如此。

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

Polyfills可用于Internet Explorer和Edge;https://github.com/wilddeer/stickyfill似乎是个不错的网站。