我想创建一个div,它位于一个内容块的下面,但一旦页面已经滚动到足以接触其顶部边界,就会固定在原地并与页面滚动。
当前回答
我和你有同样的问题,最终制作了一个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));
});
};
你可以简单地使用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时,元素会粘在浏览器窗口的顶部,因为是固定放置的。
最简单的解决方案(没有js): 演示
.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>
这就是我用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-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");
});
});