jQuery 使元素固定在滚动上
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15484084/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Make element fixed on scroll
提问by Kadeem L
I'm attempting to make the navigation bar stick to the top, when the user scrolls down to the nav bar and then unstick when the user scrolls back up past the navbar. I understand that this can only be implemented via JavaScript. I'm a beginner to JavaScript, so the easier the better. The JSFIDDLE is here.
我试图让导航栏粘在顶部,当用户向下滚动到导航栏,然后当用户向上滚动超过导航栏时取消粘滞。我知道这只能通过 JavaScript 实现。我是 JavaScript 的初学者,所以越简单越好。JSFIDDLE 在这里。
The HTML is as follows:
HTML如下:
<section class="main">
<div id="wrap">
<div id="featured">
<div class="wrap">
<div class="textwidget">
<div class="cup"><img src="#""></div>
<div id="header"></div></div></div></div></div></div></div>
<div class="whiteboard">
<h1><a href="#">HELLO GUYS</a></h1> </div>
</div>
<div class="bg1">
<h2> WE ARE AN EVENTS MANAGEMENT COMPANY BASED IN LONDON. </h2></div>
The CSS is as follows:
CSS如下:
.main{text-align:center;}
h1{
-webkit-font-smoothing: antialiased;
display:inline-block;
font: 800 1.313em "proxima-nova",sans-serif;
padding: 10px 10px;
margin: 20px 20px;
letter-spacing: 8px;
text-transform: uppercase;
font-size:3.125em;
text-align: center;
max-width: 606px;
line-height: 1.45em;
position: scroll;
background-color:#e94f78;
text-decoration: none;
color:yellow;
background-image:url;
}
h1 a{
text-decoration: none;
color:yellow;
padding-left: 0.15em;
}
h2{
-webkit-font-smoothing: antialiased;
display:inline-block;
font: 800 1.313em "proxima-nova",sans-serif;
letter-spacing: 8px;
margin-top: 100px;
text-transform: uppercase;
font-size:3.125em;
text-align: center;
line-height: 1.45em;
position: scroll;
text-decoration: none;
color:white;
z-index: -9999;
}
h2 a{
text-decoration: none;
color:white;
padding-left: 0.15em;
}
h5{
position: absolute;
font-family:sans-serif;
font-weight:bold;
font-size:40px;
text-align: center;
float: right;
background-color:#fff;
margin-top: -80px;
margin-left: 280px;
}
h5 a{
text-decoration: none;
color:red;
}
h5 a:hover{
color:yellow;
}
#text1{
-webkit-font-smoothing: antialiased;
display:inline-block;
font: 800 1.313em "proxima-nova",sans-serif;
margin: 20px 20px;
letter-spacing: 8px;
text-transform: uppercase;
font-size:3.125em;
text-align: center;
max-width: 606px;
line-height: 1.45em;
position: scroll;
background-color:#E94F78;
}
#text1 a{
color:yellow;
text-decoration: none;
padding-left: 0.15em;
}
#text1 a:hover{
text-decoration: none;
cursor:pointer;
}
.whiteboard{
background-image:url(http://krystalrae.com/img/krystalrae-2012-fall-print-leopard-sketch.jpg);
background-position: center;
padding: ;
background-color: #fff;
z-index: 1000;
}
.bg{
height:2000px;
background-color:#ff0;
background-image:url(http://alwayscreative.net/images/stars-last.jpg);
position:relative;
z-index: -9999;
}
.bg1{
background-image:url(http://alwayscreative.net/images/stars-last.jpg);
z-index: -9999;
height:1000px;
}
/* Header */
#wrap {
margin: 0 auto;
padding: 0;
width: 100%;
}
#featured {
background: #E94F78 url(http://www.creativityfluid.com/wp-content/themes/creativityfluid/images/img-bubbles-red.png) no-repeat top;
background-size: 385px 465px;
color: #fff;
height: 535px;
overflow: hidden;
position: relative;
z-index: -2;
}
#featured .wrap {
overflow: hidden;
clear: both;
padding: 70px 0 30px;
position: fixed;
z-index: -1;
width: 100%;
}
#featured .wrap .widget {
width: 80%;
max-width: 1040px;
margin: 0 auto;
}
#featured h1,
#featured h3,
#featured p {
color: yellow;
text-shadow: none;
}
#featured h4{
color:white;
text-shadow:none;
}
#featured h4 {
margin: 0 0 30px;
}
#featured h3 {
font-family: 'proxima-nova-sc-osf', arial, serif;
font-weight: 600;
letter-spacing: 3px;
}
#featured h1 {
margin: 0;
}
.textwidget{
padding: 0;
}
.cup{
margin-top:210px;
z-index: 999999;
}
.container{font-size:14px; margin:0 auto; width:960px}
.test_content{margin:10px 0;}
.scroller_anchor{height:0px; margin:0; padding:0;background-image:url()}
.scroller{background:#FFF;
background-image:url(http://krystalrae.com/img/krystalrae-2012-fall-print-leopard-sketch.jpg);
margin:0 0 10px; z-index:100; height:50px; font-size:18px; font-weight:bold; text-align:center; width:960px;}
回答by tschiela
You can do that with some easy jQuery:
你可以用一些简单的 jQuery 来做到这一点:
var elementPosition = $('#navigation').offset();
$(window).scroll(function(){
if($(window).scrollTop() > elementPosition.top){
$('#navigation').css('position','fixed').css('top','0');
} else {
$('#navigation').css('position','static');
}
});
回答by Shawn Whinnery
I wouldn't bother with jQuery or LESS. A javascript framework is overkill in my opinion.
我不会打扰 jQuery 或 LESS。在我看来,javascript 框架太过分了。
window.addEventListener('scroll', function (evt) {
// This value is your scroll distance from the top
var distance_from_top = document.body.scrollTop;
// The user has scrolled to the tippy top of the page. Set appropriate style.
if (distance_from_top === 0) {
}
// The user has scrolled down the page.
if(distance_from_top > 0) {
}
});
回答by Beat Richartz
There are some problems implementing this which the original accepted answer does not answer:
实现这个有一些问题,原始接受的答案没有回答:
- The
onscroll
event of the window is firing very often. This implies that you either have to use a very performant listener, or you have to delay the listener somehow. jQuery Creator John Resig states herehow a delayed mechanism can be implemented, and the reasons why you should do it. In my opinion, given todays browsers and environments, a performant listener will do as well. Here is an implementation of the pattern suggested by John Resig - The way position:fixed works in css, if you scroll down the page and move an element from position:static to
position: fixed
, the page will "jump" a little because the document "looses" the height of the element. You can get rid of that by adding the height to thescrollTop
and replace the lost height in the document body with another object. You can also use that object to determine if the sticky item has already been moved toposition: fixed
and reduce the calls to the code revertingposition: fixed
to the original state: Look at the fiddle here - Now, the only expensive thing in terms of performance the handler is really doing is calling
scrollTop
on every call. Since the interval bound handler has also its drawbacks, I'll go as far as to argue here that you can reattach the event listener to the original scroll Event to make it feel snappier without many worries. You'll have to profile it though, on every browser you target / support. See it working here
- 该
onscroll
窗口的事件经常开火。这意味着您要么必须使用高性能的侦听器,要么必须以某种方式延迟侦听器。jQuery Creator John Resig在此阐述了如何实现延迟机制,以及您应该这样做的原因。在我看来,鉴于当今的浏览器和环境,高性能监听器也可以。这是 John Resig 建议的模式的实现 - position:fixed 在 css 中的工作方式,如果你向下滚动页面并将一个元素从 position:static 移动到
position: fixed
,页面会“跳跃”一点,因为文档“松散”了元素的高度。您可以通过将高度添加到scrollTop
并用另一个对象替换文档正文中丢失的高度来摆脱它。您还可以使用该对象来确定粘性项目是否已移至position: fixed
并减少对恢复position: fixed
到原始状态的代码的调用:查看此处的小提琴 - 现在,处理程序在性能方面真正做的唯一昂贵的事情是
scrollTop
在每次调用时调用。由于间隔绑定处理程序也有其缺点,我将在这里论证您可以将事件侦听器重新附加到原始滚动事件,使其感觉更快捷,而不必担心。但是,您必须在您定位/支持的每个浏览器上对其进行概要分析。看到它在这里工作
Here's the code:
这是代码:
JS
JS
/* Initialize sticky outside the event listener as a cached selector.
* Also, initialize any needed variables outside the listener for
* performance reasons - no variable instantiation is happening inside the listener.
*/
var sticky = $('#sticky'),
stickyClone,
stickyTop = sticky.offset().top,
scrollTop,
scrolled = false,
$window = $(window);
/* Bind the scroll Event */
$window.on('scroll', function (e) {
scrollTop = $window.scrollTop();
if (scrollTop >= stickyTop && !stickyClone) {
/* Attach a clone to replace the "missing" body height */
stickyClone = sticky.clone().prop('id', sticky.prop('id') + '-clone')
stickyClone = stickyClone.insertBefore(sticky);
sticky.addClass('fixed');
} else if (scrollTop < stickyTop && stickyClone) {
/* Since sticky is in the viewport again, we can remove the clone and the class */
stickyClone.remove();
stickyClone = null;
sticky.removeClass('fixed');
}
});
CSS
CSS
body {
margin: 0
}
.sticky {
padding: 1em;
background: black;
color: white;
width: 100%
}
.sticky.fixed {
position: fixed;
top: 0;
left: 0;
}
.content {
padding: 1em
}
HTML
HTML
<div class="container">
<div id="page-above" class="content">
<h2>Some Content above sticky</h2>
...some long text...
</div>
<div id="sticky" class="sticky">This is sticky</div>
<div id="page-content" class="content">
<h2>Some Random Page Content</h2>...some really long text...
</div>
</div>
回答by AlexTR
Here you go, no frameworks, short and simple:
给你,没有框架,简短而简单:
var el = document.getElementById('elId');
var elTop = el.getBoundingClientRect().top - document.body.getBoundingClientRect().top;
window.addEventListener('scroll', function(){
if (document.documentElement.scrollTop > elTop){
el.style.position = 'fixed';
el.style.top = '0px';
}
else
{
el.style.position = 'static';
el.style.top = 'auto';
}
});
回答by tim.baker
You want to use jQuery WayPoints. It is a very simple plugin and acheives exactly what you have described.
您想使用jQuery WayPoints。这是一个非常简单的插件,可以完全达到您所描述的效果。
Most straightforward implementation
最直接的实现
$('.thing').waypoint(function(direction) {
alert('Top of thing hit top of viewport.');
});
You will need to set some custom CSS to set exactly where it does become stuck, this is normal though for most ways to do it.
您需要设置一些自定义 CSS 以准确设置它卡住的位置,尽管对于大多数方法来说这是正常的。
This pagewill show you all the examples and info that you need.
此页面将显示您需要的所有示例和信息。
For future reference a example of it stopping and starting is this website. It is a "in the wild" example.
为了将来参考,它停止和启动的一个例子是这个网站。这是一个“在野外”的例子。
回答by Huangism
You can go to LESS CSS website http://lesscss.org/
你可以去 LESS CSS 网站http://lesscss.org/
Their dockable menu is light and performs well. The only caveat is that the effect takes place after the scroll is complete. Just do a view source to see the js.
他们的可停靠菜单很轻而且性能很好。唯一需要注意的是,效果发生在滚动完成后。只需做一个查看源代码即可查看js。
回答by Fredericofrg
You can do this with css too.
你也可以用 css 来做到这一点。
just use position:fixed;
for what you want to be fixed when you scroll down.
position:fixed;
当您向下滚动时,仅用于您想要修复的内容。
you can have some examples here:
你可以在这里有一些例子:
http://davidwalsh.name/demo/css-fixed-position.php
http://davidwalsh.name/demo/css-fixed-position.php
http://demo.tutorialzine.com/2010/06/microtut-how-css-position-works/demo.html
http://demo.tutorialzine.com/2010/06/microtut-how-css-position-works/demo.html
回答by T.Todua
Plain Javascript Solution (DEMO) :
纯 Javascript 解决方案(演示):
<br/><br/><br/><br/><br/><br/><br/>
<div>
<div id="myyy_bar" style="background:red;"> Here is window </div>
</div>
<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
<script type="text/javascript">
var myyElement = document.getElementById("myyy_bar");
var EnableConsoleLOGS = true; //to check the results in Browser's Inspector(Console), whenever you are scrolling
// ==============================================
window.addEventListener('scroll', function (evt) {
var Positionsss = GetTopLeft ();
if (EnableConsoleLOGS) { console.log(Positionsss); }
if (Positionsss.toppp > 70) { myyElement.style.position="relative"; myyElement.style.top = "0px"; myyElement.style.right = "auto"; }
else { myyElement.style.position="fixed"; myyElement.style.top = "100px"; myyElement.style.right = "0px"; }
});
function GetOffset (object, offset) {
if (!object) return;
offset.x += object.offsetLeft; offset.y += object.offsetTop;
GetOffset (object.offsetParent, offset);
}
function GetScrolled (object, scrolled) {
if (!object) return;
scrolled.x += object.scrollLeft; scrolled.y += object.scrollTop;
if (object.tagName.toLowerCase () != "html") { GetScrolled (object.parentNode, scrolled); }
}
function GetTopLeft () {
var offset = {x : 0, y : 0}; GetOffset (myyElement.parentNode, offset);
var scrolled = {x : 0, y : 0}; GetScrolled (myyElement.parentNode.parentNode, scrolled);
var posX = offset.x - scrolled.x; var posY = offset.y - scrolled.y;
return {lefttt: posX , toppp: posY };
}
// ==============================================
</script>
回答by Anup
window.addEventListener("scroll", function(evt) {
var pos_top = document.body.scrollTop;
if(pos_top == 0){
$('#divID').css('position','fixed');
}
else if(pos_top > 0){
$('#divId').css('position','static');
}
});
回答by Sharad
Most easiest way to do it as follow:
最简单的方法如下:
var elementPosition = $('#navigation').offset();
$(window).scroll(function(){
if($(window).scrollTop() > elementPosition.top){
$('#navigation').css('position','fixed').css('top','0');
} else {
$('#navigation').css('position','static');
}
});