我想創(chuàng)建一個div,它位于一個內(nèi)容塊的下面,但是一旦頁面滾動到足以接觸到它的頂部邊界,它就會固定在適當(dāng)?shù)奈恢茫㈦S頁面一起滾動。
您可以簡單地使用css,將元素定位為固定的:
.fixedElement {
background-color: #c0c0c0;
position:fixed;
top:0;
width:100%;
z-index:100;
}
編輯:你應(yīng)該有絕對位置的元素,一旦滾動偏移量到達元素,它應(yīng)該被更改為固定的,頂部位置應(yīng)該被設(shè)置為零。
您可以使用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'});
}
});
當(dāng)滾動偏移量達到200時,元素將貼在瀏覽器窗口的頂部,因為被放置為固定的。
你已經(jīng)在Google Code的發(fā)布頁面和Stack Overflow的編輯頁面上看到了這個例子。
當(dāng)你向上滾動時,CMS的回答不會恢復(fù)定位。以下是從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>
和一個簡單的現(xiàn)場演示。
一個新生的、無腳本的替代品是position: sticky,Chrome、Firefox和Safari都支持它。參見HTML5Rocks和demo上的文章,以及Mozilla docs。
截至2017年1月,以及Chrome 56的發(fā)布,大多數(shù)常用的瀏覽器都支持CSS中的position: sticky屬性。
#thing_to_stick {
position: sticky;
top: 0;
}
在Firefox和Chrome上對我很管用。
在Safari中你仍然需要使用position: -webkit-sticky。
聚合填充可用于Internet Explorer和Edgehttps://github.com/wilddeer/stickyfill似乎是一個好地方。
以下是不使用jquery的方法(更新:參見其他答案,現(xiàn)在只使用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 . sticky panel/main . htm
這是我用jquery做的。這些都是從堆棧溢出的各種答案中拼湊出來的。這個解決方案緩存了選擇器以獲得更快的性能,并且解決了當(dāng)粘性div變得粘性時的“跳躍”問題。
請登錄js fiddle: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);
}
});
});
正如Josh Lee和Colin t Hart所說,你可以選擇使用位置:粘性;top:0;應(yīng)用于您希望滾動的div...
此外,您唯一需要做的就是將它復(fù)制到頁面頂部,或者將其格式化以適合外部CSS表單:
<style>
#sticky_div's_name_here { position: sticky; top: 0; }
</style>
只需將#sticky_div的_name_here替換為您的div的名稱,即如果您的div是& ltdiv id = " example " & gt您應(yīng)該將# example { position:sticky;top:0;}.
這是另一個選擇:
java描述語言
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應(yīng)該以position:absolute CSS屬性開始。
這里還有一個版本,供那些與其他版本有問題的人嘗試。它將這個重復(fù)問題中討論的技術(shù)結(jié)合在一起,動態(tài)生成所需的助手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();
}
要使元素具有粘性,請執(zhí)行以下操作:
make_sticky('#sticky-elem-id');
當(dāng)元素變得粘滯時,代碼管理剩余內(nèi)容的位置,以防止它跳到粘滯元素留下的空隙中。當(dāng)滾動回到粘性元素上方時,它也將粘性元素返回到其原始的非粘性位置。
我的解決方案有點冗長,但它處理了居中布局中從左邊緣開始的變量定位。
// 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));
});
};
以下是喬希·李回答的延伸版本。如果您希望div位于右側(cè)邊欄上,并在一個范圍內(nèi)浮動(即,您需要指定頂部和底部錨點位置)。它還修復(fù)了在移動設(shè)備上查看時的一個錯誤(您需要檢查左滾動位置,否則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();
}
我在尋找同樣的東西時發(fā)現(xiàn)了這個。我知道這是一個老問題,但我想我會提供一個更近的答案。
Scrollorama有一個“鎖定”功能,這正是我一直在尋找的。
http://johnpolacek.github.io/scrollorama/
Evan,回答另一個問題時提供的信息可能對你有所幫助:
滾動后檢查元素是否可見
基本上,只有在驗證了document.body.scrollTop值等于或大于元素的頂部之后,才需要修改元素的樣式,將其設(shè)置為fixed。
已接受的答案有效,但如果您在上面滾動,則不會返回到之前的位置。放在那里之后總是粘在上面。
$(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的回應(yīng)可能會起作用,但我無法讓它起作用。他的示例頁面也不起作用(對我來說)。
您可以額外添加3行,這樣當(dāng)用戶滾動回頂部時,div將停留在原來的位置:
代碼如下:
if ($(this).scrollTop() < 200 && $el.css('position') == 'fixed'){
$('.fixedElement').css({'position': 'relative', 'top': '200px'});
}
我在一個div中設(shè)置了鏈接,所以這是一個字母和數(shù)字鏈接的垂直列表。
#links {
float:left;
font-size:9pt;
margin-left:0.5em;
margin-right:1em;
position:fixed;
text-align:center;
width:0.8em;
}
然后,我設(shè)置了這個方便的jQuery函數(shù)來保存加載的位置,并在滾動超過該位置時將位置更改為fixed。
注意:這只適用于鏈接在頁面加載時可見的情況!!
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)');
}
});
在javascript中,您可以:
var element = document.getElementById("myid");
element.style.position = "fixed";
element.style.top = "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");
});
});
我用上面的一些工作創(chuàng)造了這項技術(shù)。我稍微改進了一下,想分享一下我的作品。希望這有所幫助。
jsfiddle代碼
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();?
這是一種更有活力的滾動方式。它確實需要一些工作,我會在某個時候把它變成一個插件,但這是我在工作一小時后想出的。
我也有類似的問題——我有一個div,它已經(jīng)浮動在CSS定義的其他內(nèi)容之上的“固定”位置。我想要實現(xiàn)的是,當(dāng)我向下滾動頁面時,div會開始向下滾動內(nèi)容,但會停留在頁面的頂部(即永遠不會消失)。
我的div的樣式是:
.inProjectNavigation {
width: 60.5%;
max-width: 1300px;
position: fixed; top: 60%;
display: block;
}
我只需將這個div放在頁面的某個地方,它就會出現(xiàn)在內(nèi)容的頂部。對其父母的風(fēng)格沒有特殊要求。
讓它堅持到頂端的JS是:
const MIN_TOP_POSITION = 30;
/**
* Make the project navigation initially scroll down with the page, but then stick to the top of the browser
*/
$(window).scroll(function(e){
let $navigationDiv = $('.inProjectNavigation');
let originalTopPosPx = $navigationDiv.attr('data-originalTopPosPx');
//-- on first scroll, save the original px position in the element, as defined by CSS
if (originalTopPosPx == null) {
let cssValue = $navigationDiv.css('top');
originalTopPosPx = cssValue.substring(0, cssValue.length - 2); // get rid of the 'px'
$navigationDiv.attr('data-originalTopPosPx', originalTopPosPx);
}
//-- follow the scroll, but stick to top
$navigationDiv.css({'top': Math.max(MIN_TOP_POSITION, (originalTopPosPx - $(this).scrollTop())) + 'px'});
});
在Mac - Safari、Firefox和Chrome上測試。希望也能在IE中工作:)
您可以不使用javascript,通過使用:
.element_to_stick {
position: sticky;
top: 0px; // Top calculated from div Parent, not top screen !
}
在Safari中你仍然需要使用position: -webkit-sticky。
不是一個精確的解決方案,但可以考慮一個很好的選擇
這個CSS只在屏幕頂部有滾動條。只用CSS解決了所有問題,不用JavaScript,不用JQuery,不用動腦(lol)。
享受我的小提琴:D所有的代碼都包括在那里:)
半鑄鋼?鋼性鑄鐵(Cast Semi-Steel)
#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">
把內(nèi)容放得足夠長,這樣你就可以在這里看到效果了:) 哦,參考資料也在里面,因為他值得表揚
僅CSS屏幕頂部滾動條
粘滯直到頁腳碰到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);