jQuery 如何在滚动时修复标题

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19158559/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 23:19:33  来源:igfitidea点击:

How to fix a header on scroll

jquerycssheaderfixed

提问by Paul Designer

I am creating a header that once scrolled to a certain amount of pixels it fixes and stays in place.

我正在创建一个标题,一旦滚动到一定数量的像素,它就会修复并保持原位。

Can I do this using just css and html or do i need jquery too?

我可以只使用 css 和 html 来做到这一点,还是我也需要 jquery?

I have created a demo so you can understand. Any help would be great!

我已经创建了一个演示,所以你可以理解。任何帮助都会很棒!

http://jsfiddle.net/gxRC9/4/

http://jsfiddle.net/gxRC9/4/

body{
    margin:0px;
    padding:0px;
}
.clear{
    clear:both;
}
.container{
    height:2000px;
}
.cover-photo-container{
width:700px;
height: 348px;
margin-bottom: 20px;
background-color:red;
}

.small-box{
    width:163px;
    height:100px;
    border:1px solid blue;
    float:left;
}

.sticky-header{
    width:700px;
    height:50px;
    background:orange;
    postion:fixed;
}

回答by Coop

You need some JS to do scroll events. The best way to do this is to set a new CSS class for the fixed position that will get assigned to the relevant div when scrolling goes past a certain point.

你需要一些 JS 来做滚动事件。最好的方法是为固定位置设置一个新的 CSS 类,当滚动超过某个点时,该类将分配给相关的 div。

HTML

HTML

<div class="sticky"></div>

CSS

CSS

.fixed {
    position: fixed;
    top:0; left:0;
    width: 100%; }

jQuery

jQuery

$(window).scroll(function(){
  var sticky = $('.sticky'),
      scroll = $(window).scrollTop();

  if (scroll >= 100) sticky.addClass('fixed');
  else sticky.removeClass('fixed');
});

Example fiddle: http://jsfiddle.net/gxRC9/501/

小提琴示例:http: //jsfiddle.net/gxRC9/501/



EDIT: Extended example

编辑:扩展示例

If the trigger point is unknown but should be whenever the sticky element reaches the top of the screen, offset().topcan be used.

如果触发点未知但应该在粘性元素到达屏幕顶部时,offset().top可以使用。

var stickyOffset = $('.sticky').offset().top;

$(window).scroll(function(){
  var sticky = $('.sticky'),
      scroll = $(window).scrollTop();

  if (scroll >= stickyOffset) sticky.addClass('fixed');
  else sticky.removeClass('fixed');
});

Extended example fiddle: http://jsfiddle.net/gxRC9/502/

扩展示例小提琴:http: //jsfiddle.net/gxRC9/502/

回答by Mobeen Abdullah

I have modified the Coop's answer. Please check the example FIDDLEHere's my edits:

我修改了 Coop 的答案。请检查示例FIDDLE这是我的编辑:

$(window).scroll(function(){
  if ($(window).scrollTop() >= 330) {
    $('.sticky-header').addClass('fixed');
   }
   else {
    $('.sticky-header').removeClass('fixed');
   }
});

回答by Rich

I know Coop has already answered this question, but here is a version which also tracks where in the document the div is, rather than relying on a static value:

我知道 Coop 已经回答了这个问题,但这里有一个版本,它也跟踪 div 在文档中的位置,而不是依赖于静态值:

http://jsfiddle.net/gxRC9/16/

http://jsfiddle.net/gxRC9/16/

Javascript

Javascript

var offset = $( ".sticky-header" ).offset();
var sticky = document.getElementById("sticky-header")

$(window).scroll(function() {

    if ( $('body').scrollTop() > offset.top){
        $('.sticky-header').addClass('fixed');
    } else {
         $('.sticky-header').removeClass('fixed');
    } 

});

CSS

CSS

.fixed{
     position: fixed;
    top: 0px;
}

回答by RubenSandwich

Coop's answer is excellent.
However it depends on jQuery, here is a version that has no dependencies:

Coop的回答非常好。
但是它依赖于 jQuery,这是一个没有依赖项的版本:

HTML

HTML

<div id="sticky" class="sticky"></div>

CSS

CSS

.sticky {
  width: 100%
}

.fixed {
  position: fixed;
  top:0;
}

JS
(This uses eyelidlessness's answerfor finding offsets in Vanilla JS.)

JS
(这使用eyelidless 的答案在 Vanilla JS 中查找偏移量。)

function findOffset(element) {
  var top = 0, left = 0;

  do {
    top += element.offsetTop  || 0;
    left += element.offsetLeft || 0;
    element = element.offsetParent;
  } while(element);

  return {
    top: top,
    left: left
  };
}

window.onload = function () {
  var stickyHeader = document.getElementById('sticky');
  var headerOffset = findOffset(stickyHeader);

  window.onscroll = function() {
    // body.scrollTop is deprecated and no longer available on Firefox
    var bodyScrollTop = document.documentElement.scrollTop || document.body.scrollTop;

    if (bodyScrollTop > headerOffset.top) {
      stickyHeader.classList.add('fixed');
    } else {
      stickyHeader.classList.remove('fixed');
    }
  };
};

Example

例子

https://jsbin.com/walabebita/edit?html,css,js,output

https://jsbin.com/walabebita/edit?html,css,js,output

回答by crdunst

Just building on Rich's answer, which uses offset.

只是建立在Rich's answer 的基础上,它使用了偏移量。

I modified this as follows:

我对此进行了如下修改:

  • There was no need for the var $stickyin Rich's example, it wasn't doing anything
  • I've moved the offset check into a separate function, and called it on document ready as well as on scroll so if the page refreshes with the scroll half-way down the page, it resizes straight-away without having to wait for a scroll trigger

    jQuery(document).ready(function($){
        var offset = $( "#header" ).offset();
        checkOffset();
    
        $(window).scroll(function() {
            checkOffset();
        });
    
        function checkOffset() {
            if ( $(document).scrollTop() > offset.top){
                $('#header').addClass('fixed');
            } else {
                $('#header').removeClass('fixed');
            } 
        }
    
    });
    
  • $stickyRich 的例子中不需要 var ,它没有做任何事情
  • 我已经将偏移检查移到一个单独的函数中,并在文档准备好和滚动时调用它,所以如果页面在页面向下滚动时刷新,它会立即调整大小而无需等待滚动扳机

    jQuery(document).ready(function($){
        var offset = $( "#header" ).offset();
        checkOffset();
    
        $(window).scroll(function() {
            checkOffset();
        });
    
        function checkOffset() {
            if ( $(document).scrollTop() > offset.top){
                $('#header').addClass('fixed');
            } else {
                $('#header').removeClass('fixed');
            } 
        }
    
    });
    

回答by ocket8888

Glorious, Pure-HTML/CSS Solution

光荣的纯 HTML/CSS 解决方案

In 2019 with CSS3 you can do this without Javascript at all. I frequently make sticky headers like this:

在 2019 年,使用 CSS3,您完全可以在没有 Javascript 的情况下做到这一点。我经常制作这样的粘性标题:

body {
  overflow-y: auto;
  margin: 0;
}

header {
  position: sticky; /* Allocates space for the element, but moves it with you when you scroll */
  top: 0; /* specifies the start position for the sticky behavior - 0 is pretty common */
  width: 100%;
  padding: 5px 0 5px 15px;
  color: white;
  background-color: #337AB7;
  margin: 0;
}

h1 {
  margin: 0;
}

div.big {
  width: 100%;
  min-height: 150vh;
  background-color: #1ABB9C;
  padding: 10px;
}
<body>
<header><h1>Testquest</h1></header>
<div class="big">Just something big enough to scroll on</div>
</body>

回答by Craig Jacobs

Coops answer is a good, simple solution, however, once you apply the fixed class the page becomes that much shorter and content will "jump" up, and if page is of a length where the scroll distance is less than the height of the header element, it will appear to jump and not let you see the bottom of the page.

Coops 的答案是一个很好的、简单的解决方案,但是,一旦您应用了固定类,页面就会变得更短并且内容会“跳”起来,并且如果页面的长度滚动距离小于页眉的高度元素,它会出现跳转而不会让您看到页面底部。

The answer I found was to add a spacer div above the element that will become fixed (nav element in my case), and set it to the same height as the nav element, and set it to display none.

我找到的答案是在将固定的元素(在我的例子中是导航元素)上方添加一个间隔 div,并将其设置为与导航元素相同的高度,并将其设置为不显示。

When adding the .fixed class to the nav, show the .nav-spacer div, and when removing it, hide it. Since the height of the page changes instantly I have set the duration to 0.

将 .fixed 类添加到导航时,显示 .nav-spacer div,删除时将其隐藏。由于页面的高度会立即更改,因此我将持续时间设置为 0。

HTML

HTML

<header>the element above the element that will become fixed</header>
<div class="nav-spacer"></div>
<nav></nav>

CSS

CSS

nav {
    position: relative;    
    height: 100px;
}
.nav-spacer{
    position: relative;
    height: 100px;
    display: none;
}
.fixed {
    position: fixed;
    top:0;
    left:0;
    width: 100%;
    /* I like to add a shadow on to the fixed element */
    -webkit-box-shadow: 0px 5px 10px 1px rgba(0,0,0,0.25);
    -moz-box-shadow: 0px 5px 10px 1px rgba(0,0,0,0.25);
    box-shadow: 0px 5px 10px 1px rgba(0,0,0,0.25);
}

JavaScript

JavaScript

var stickyOffset = $('nav').offset().top;

$(window).scroll(function(){
    if ($(window).scrollTop() >= stickyOffset){
        $('nav').addClass('fixed');
        //this makes the page length equal to what it was before fixing nav
        $('.nav-spacer').show(0); 
    }
    else {
        $('nav').removeClass('fixed');
        $('.nav-spacer').hide(0);
    }
});

回答by Oni Victor

Or just simply add a spantag with the height of the fixed header set as its height then insert it next to the sticky header:

或者只是简单地添加一个span标签,将固定标题的高度设置为其高度,然后将其插入到粘性标题旁边:

$(function() {
  var $span_height = $('.fixed-header').height;
  var $span_tag = '<span style="display:block; height:' + $span_height + 'px"></span>';

  $('.fixed-header').after($span_tag);
});

回答by arjun

 $(document).ready(function(){

    var div=$('#header');
    var start=$(div).offset().top;

    $.event.add(window,'scroll',function(){
        var p=$(window).scrollTop();
        $(div).css('position',(p>start)?'fixed':'static');
        $(div).css('top',(p>start)?'0px':'');

    }); 
});

It works perfectly.

它完美地工作。

回答by Daniel

The chosen solution did not fit well in my page. So this is a more advanced version that works with bootstrap.

选择的解决方案不适合我的页面。所以这是一个更高级的版本,可以与引导程序一起使用。

The javascript

javascript

var stickyOffset = $('.sticky-header').offset().top;

$(window).scroll(function () {
    var sticky = $('.sticky-header'),
        scroll = $(window).scrollTop(),
        header = $('.fixed-header-background');
    sticky.each(function() {
        var left = $(this).offset().left;
        $(this).data('left', left);//I store the left offset
    });

    if (scroll >= stickyOffset) {
        sticky.addClass('fixed');
        header.css('display', 'block');
        sticky.each(function() {
            $(this).css('left', $(this).data('left'));//I set the left offset
        });
    } else {
        sticky.removeClass('fixed');
        header.css('display', 'none');
        sticky.each(function () {
            $(this).css('left', '');//I remove the left offset
        });
    }
});

The CSS

CSS

.fixed-header-background {
    display: none;
     position: fixed;
    top: 50px;
    width: 100%;
    height: 30px;
    background-color: #fff;
    z-index: 5;
    border-bottom-style: solid;
    border-bottom-color: #dedede;
    border-bottom-width: 2px;
}

.fixed{
     position: fixed;
    top: 52px;
    z-index: 6;
}

And the HTML

和 HTML

    <div class="fixed-header-background"></div>
<table class="table table-hover table-condensed">
        <thead>
            <tr>
                <th></th>
                <th><span class="sticky-header">My header 1</span></th>
                <th><span class="sticky-header">My header 2</span></th>
            </tr>
        </thead>
        <tbody>
[....]

        </tbody>
    </table>