如何在滚动上修复标题

时间:2013-10-03 11:54:34

标签: jquery css header fixed

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

我可以使用css和html执行此操作,还是需要jquery?

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

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

15 个答案:

答案 0 :(得分:101)

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

<强> HTML

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

<强> CSS

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

<强>的jQuery

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

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

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


编辑:扩展示例

如果触发点未知,但只要粘性元素到达屏幕顶部,就可以使用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');
});

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

答案 1 :(得分:11)

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

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

答案 2 :(得分:9)

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

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

<强>的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

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

答案 3 :(得分:7)

Coop的答案非常好 但是它依赖于jQuery,这是一个没有依赖关系的版本:

<强> HTML

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

<强> CSS

.sticky {
  width: 100%
}

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

<强> JS
(这使用eyelidlessness's answer来查找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');
    }
  };
};

示例

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

答案 4 :(得分:5)

只需使用偏移量Rich's answer构建。

我修改了如下:

  • 在Rich的例子中没有必要使用var $sticky,它没有做任何事情
  • 我已将偏移检查移动到一个单独的函数中,并将其调用 在文档就绪以及滚动,所以如果页面刷新与 在页面中间向下滚动,它可以直接调整大小而无需等待滚动触发器

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

答案 5 :(得分:5)

Coops答案是一个很好的,简单的解决方案,但是,一旦你应用了固定的类,页面变得更短,内容将会跳过&#34;跳跃&#34;向上,如果页面的长度是滚动距离小于标题元素的高度,它将显示为跳转,不会让您看到页面的底部。

我找到的答案是在要修复的元素上方添加一个spacer div(在我的情况下为nav元素),并将其设置为与nav元素相同的高度,并将其设置为none。

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

<强> HTML

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

<强> 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

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

答案 6 :(得分:2)

或者只是添加一个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);
});

答案 7 :(得分:1)

 $(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':'');

    }); 
});

效果很好。

答案 8 :(得分:1)

所选择的解决方案不适合我的页面。所以这是一个更高级的版本,适用于bootstrap。

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

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

和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>

答案 9 :(得分:1)

光荣的纯HTML / CSS解决方案

在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>

答案 10 :(得分:1)

custom scroll Header Fixed in shopify:

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

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


css:


header.site-header.border-bottom.logo--left.fixed {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 9;
}

答案 11 :(得分:0)

希望这一个替代解决方案对其他人来说和我一样有价值。

情况
在HTML5页面中,我有一个菜单,它是标题内的导航元素(不是THE标题,而是另一个元素中的标题)。
一旦用户滚动到导航栏,我希望导航贴在顶部,但在此之前,标题是绝对定位的(所以我可以稍微覆盖其他内容)。
上面的解决方案从未触发过更改,因为.offsetTop不会改变,因为这是一个绝对定位的元素。此外,.scrollTop属性只是最顶层元素的顶部...也就是说0并且始终为0 我使用这两个进行的任何测试(和getBoundingClientRect结果一样)都不会告诉我导航栏的顶部是否滚动到可查看页面的顶部(再次,如在控制台中报告的那样,他们只是在滚动时保持相同的数字发生了)。

的解决方案
我的解决方案是利用

window.visualViewport.pageTop

pageTop属性的值反映了屏幕的可视部分,因此允许我跟踪元素引用可视区域边界的位置。
这允许分配给窗口的滚动事件的简单函数来检测导航栏的顶部何时与可视区域的顶部相交并应用样式以使其粘在顶部。

可能没必要说,无论何时我正在处理滚动,我希望使用此解决方案以编程方式响应滚动元素的移动。
希望能帮到别人。

答案 12 :(得分:0)

最简单的方法是: HTML:

<header>
        <h1>Website</h1>
</header>

CSS:

header{
    position: sticky;
    top: 0;
}

答案 13 :(得分:0)

如果您使用的是 React,我最近发布了 a custom hook,它使您能够做到这一点。您需要提供对粘性元素的引用以及对希望它粘在其顶部的元素的引用。它还会为您处理屏幕“跳转”(如其他回复中所述)。

const sticky = useRef<HTMLDivElement>(null)
const container = useRef<HTMLDivElement>(null)

useStickyScroll({
    element: sticky,
    container: container
})

答案 14 :(得分:0)

如果用户从下到上滚动文档,我的显示标题的解决方案。

JS:

const isMobile = window.innerWidth < 768
const $header = $('#header')
let lastScrollTop = 0
if ( isMobile ) {
    $(window).scroll(function () {
        const scrollTop = window.pageYOffset || document.documentElement.scrollTop

        if ( scrollTop < lastScrollTop ) {
            $header.removeClass('header_top')
        } else {
            $header.addClass( 'header_top' )    
        }

        lastScrollTop = scrollTop <= 0 ? 0 : scrollTop
    })
}

CSS

.header {
    position: fixed;
    top: 0;
    z-index: 70;
    width: 100vw;
    transition: top .5s;
    height: 62px;
}
.header_top {
    top: -62px;
}