如何在滚动上修复标题

问题描述 投票:39回答:11

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

我可以使用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;
}
jquery css header fixed
11个回答
105
投票

你需要一些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/


2
投票

选择的解决方案不适合我的页面。所以这是一个与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>

0
投票

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

解 我的解决方案是利用

window.visualViewport.pageTop

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

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


14
投票

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

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

10
投票

我知道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;
}

9
投票

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


6
投票

Coops答案是一个很好的,简单的解决方案,但是,一旦你应用固定类,页面变得更短,内容将“跳”起来,如果页面的长度是滚动距离小于标题的高度它会跳转,不会让你看到页面的底部。

我找到的答案是在要修复的元素上面添加一个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
投票

只是建立在使用偏移的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'); } } });

4
投票

Glorious, Pure-HTML/CSS Solution

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

3
投票

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

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

    }); 
});

它完美地运作。

© www.soinside.com 2019 - 2024. All rights reserved.