我怎么能让一个div坚持屏幕的顶部一旦它'被滚动?

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

659041 次浏览

你可以简单地使用css,将元素定位为固定:

.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时,元素将坚持移到浏览器窗口的顶部,因为被放置为固定。

为回答这个问题提供的信息可能对你有帮助,埃文:

检查滚动后元素是否可见

基本上,只有在验证document.body.scrollTop值等于或大于元素的顶部之后,才希望修改元素的样式,将其设置为fixed。

你已经在谷歌Code的问题页面和(最近)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>

和一个简单的现场演示

一个新兴的、无脚本的替代方法是position: sticky,它在Chrome、Firefox和Safari中得到支持。参见HTML5Rocks上的文章演示,以及Mozilla文档

接受的答案是有效的,但如果你在上面滚动,它不会回到之前的位置。它总是粘在顶部后,放在那里。

  $(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的响应应该工作,但我不能让它工作。他的示例页面也不起作用(对我来说)。

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

代码如下:

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

我有链接设置在一个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)');
}
});

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

我的解决方案有点啰嗦,但它处理变量定位从左边缘居中布局。

// 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));
});
};

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

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();​

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

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

在javascript中,你可以做:

var element = document.getElementById("myid");
element.style.position = "fixed";
element.style.top = "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>

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

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

这不是一个确切的解决方案,但却是一个很好的选择

CSS ONLY屏幕滚动条顶部。用只有CSS没有 JavaScript, 没有 JQuery, 没有 Brain work (哈哈)解决了所有问题。

享受我的小提琴: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">

把内容放长一点,这样你就可以看到效果了:) 哦,引用也在那里,因为他应该得到他的信用

CSS ONLY屏幕滚动条顶部

这是另一种选择:

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属性开始。

以下是Josh Lee的回答的扩展版本。如果你想让div在侧边栏的右边,并浮动在一个范围内(即,你需要指定顶部和底部锚位置)。它还修复了一个bug,当你在移动设备上查看这个(你需要检查左滚动位置,否则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();
}

下面是一个使用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");
});
});

我在搜索同样的东西时发现了这个。我知道这是一个老问题,但我想我可以提供一个最近的答案。

Scrollorama有一个“pin it”功能,这正是我正在寻找的。

< a href = " http://johnpolacek.github。io / scrollorama " rel = " http://johnpolacek.github.io/scrollorama/ nofollow”> < / >

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

截至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似乎是一个很好的。

正如杰克李科林·哈特所说,你可以选择只使用position: sticky; top: 0;应用到你想要滚动的div…

另外,你要做的唯一一件事就是把它复制到你的页面顶部,或者把它格式化为适合外部CSS表:

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

只需将#sticky_div's_name_here替换为div的名称,即如果您的div是<div id="example">,则将放置#example { position: sticky; top: 0; }

最简单的解决方案(没有js): 演示 < / h2 >
.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>