wake-up-neo.net

So fixieren Sie einen Header beim Scrollen

Ich erstelle einen Header, der einmal zu einer bestimmten Anzahl von Pixeln gescrollt wurde und an seinem Platz bleibt. 

Kann ich dies nur mit css und html machen oder brauche ich auch Jquery? 

Ich habe eine Demo erstellt, damit Sie verstehen können. Jede Hilfe wäre toll!

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;
}
38
Paul Designer

Sie benötigen einige JS, um Scroll-Events durchzuführen. Am besten setzen Sie dazu eine neue CSS-Klasse für die feste Position, die dem entsprechenden div zugewiesen wird, wenn der Bildlauf einen bestimmten Punkt überschreitet.

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

Beispiel Geige: http://jsfiddle.net/gxRC9/501/


EDIT: Erweitertes Beispiel

Wenn der Triggerpunkt unbekannt ist, aber immer dann angezeigt werden soll, wenn das klebrige Element den oberen Rand des Bildschirms erreicht, kann offset().top verwendet werden.

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

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

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

Erweiterte Beispiel-Geige: http://jsfiddle.net/gxRC9/502/

101
Coop

Ich habe die Antwort von Coop geändert. Bitte überprüfen Sie das Beispiel FIDDLE Hier sind meine Änderungen:

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

Ich weiß, dass Coop diese Frage bereits beantwortet hat, aber hier ist eine Version, die auch verfolgt, wo sich das div im Dokument befindet, statt sich auf einen statischen Wert zu verlassen:

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
Rich

Die Antwort von Coop ist hervorragend.
Es ist jedoch von jQuery abhängig, hier ist eine Version, die keine Abhängigkeiten hat:

HTML

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

CSS

.sticky {
  width: 100%
}

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

JS
(Diese Antwort verwendet Eyelidlessness , um Offsets in Vanilla JS zu finden.)

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

Beispiel

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

7
RubenSandwich

Bauen Sie einfach auf Rich's answer auf, das Offset verwendet.

Ich habe das wie folgt geändert:

  • In Richs Beispiel war kein var $sticky erforderlich, es wurde nichts unternommen
  • Ich habe die Versatzprüfung in eine separate Funktion verschoben und sie sowohl beim Dokument als auch beim Scrollen als Bezeichnet. Wenn also die Seite mit dem -Scroll auf halber Höhe der Seite aktualisiert wird, ändert sich die Größe sofort auf einen Scroll-Trigger warten müssen

    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
crdunst

Herrliche, reine HTML/CSS-Lösung

Mit CSS3 können Sie dies 2019 ohne Javascript tun. Ich mache häufig klebrige Überschriften wie diese:

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>
4
ocket8888

Die Antwort von Coops ist eine gute, einfache Lösung. Wenn Sie jedoch die feste Klasse anwenden, wird die Seite viel kürzer und der Inhalt "springt" nach oben. Wenn die Seite eine Länge hat, bei der der Bildlaufabstand geringer als die Kopfhöhe ist Element wird es scheinen zu springen und Sie nicht das Ende der Seite sehen lassen. 

Die Antwort, die ich gefunden habe, war, ein Spacer div über dem Element hinzuzufügen, das fixiert wird (in meinem Fall das nav-Element), es auf die gleiche Höhe wie das nav-Element zu setzen und es auf no zu setzen.

Zeigen Sie beim Hinzufügen der .fixed-Klasse zum Nav die .nav-spacer -Datei an, und verbergen Sie sie, wenn Sie sie entfernen. Da sich die Höhe der Seite sofort ändert, habe ich die Dauer auf 0 gesetzt.

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);
    }
});
4
Craig Jacobs

Oder fügen Sie einfach ein span-Tag hinzu, dessen Höhe als Höhe festgelegt ist, und fügen Sie es neben dem klebrigen Header ein:

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

    }); 
});

Es funktioniert perfekt.

1
arjun

Die gewählte Lösung passte nicht gut zu meiner Seite. Dies ist also eine erweiterte Version, die mit Bootstrap funktioniert.

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

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

Und das 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>
1
Daniel

Hoffentlich wird dieses eine Stück einer alternativen Lösung für jemanden anderen so wertvoll sein wie für mich .

Situation:
In einer HTML5-Seite hatte ich ein Menü, das ein Nav-Element in einem Header war (nicht THE-Header, sondern ein Header in einem anderen Element).
Ich wollte, dass die Navigation an der Spitze bleibt, sobald ein Benutzer zu dieser gescrollt hat, aber vorher war der Header absolut positioniert (damit ich ihn etwas anderes überlagern konnte).
Die oben genannten Lösungen lösten nie eine Änderung aus, da .offsetTop sich nicht ändern würde, da dies ein absolut positioniertes Element war. Zusätzlich war die .scrollTop-Eigenschaft einfach das oberste Element ... also 0 und würde immer 0 sein.
Alle Tests, die ich mit diesen beiden durchgeführt habe (und dieselben mit den Ergebnissen von getBoundingClientRect), würden mir nicht sagen, ob der obere Rand der Navigationsleiste jemals auf den oberen Bereich der sichtbaren Seite blätterte Zahlen während des Bildlaufs aufgetreten sind). 

Lösung
Die Lösung für mich war zu nutzen 

window.visualViewport.pageTop

Der Wert der pageTop-Eigenschaft spiegelt den sichtbaren Bereich des Bildschirms wider, sodass ich verfolgen kann, wo sich ein Element auf die Grenzen des sichtbaren Bereichs bezieht.
Dies ermöglichte eine einfache Funktion, die dem Bildlaufereignis des Fensters zugewiesen wurde, um zu erkennen, wann der obere Teil der Navigationsleiste den oberen Bereich des sichtbaren Bereichs kreuzte, und den Stil anzuwenden, damit er am oberen Rand haften bleibt.

Wahrscheinlich unnötig zu sagen, dass ich jedes Mal, wenn ich mich mit Scrollen beschäftige, diese Lösung verwenden möchte, um programmatisch auf die Bewegung von Elementen zu reagieren, die gescrollt werden.
Hoffe es hilft jemand anderem.

0
MER