Come riparare un’intestazione su scroll

Sto creando un’intestazione che una volta scorreva fino a una certa quantità di pixel che corregge e rimane al suo posto.

Posso farlo usando solo css e html o ho anche bisogno di jQuery?

Ho creato una demo in modo da poter capire. Qualsiasi aiuto sarebbe grande!

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

Hai bisogno di un JS per fare scorrere gli eventi. Il modo migliore per farlo è impostare una nuova class CSS per la posizione fissa che verrà assegnata al relativo div quando lo scorrimento supererà un certo punto.

HTML

 

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

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


EDIT: esempio esteso

Se il punto di trigger è sconosciuto ma dovrebbe essere ogni volta che l’elemento sticky raggiunge la parte superiore dello schermo, è ansible utilizzare 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'); }); 

Esempio esteso di fiddle: http://jsfiddle.net/gxRC9/502/

Ho modificato la risposta di Coop. Si prega di controllare l’esempio FIDDLE Ecco le mie modifiche:

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

So che Coop ha già risposto a questa domanda, ma qui c’è una versione che tiene traccia di dove nel div è il documento, piuttosto che fare affidamento su un valore statico:

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

La risposta di Coop è eccellente.
Comunque dipende da jQuery, ecco una versione che non ha dipendenze:

HTML

 

CSS

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

JS
(Questo usa la risposta senza eyelness per trovare offset in 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'); } }; }; 

Esempio

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

Basandosi solo sulla risposta di Rich , che usa l’offset.

Ho modificato questo come segue:

  • Non c’era bisogno di var $sticky nell’esempio di Rich, non stava facendo nulla
  • Ho spostato il controllo offset in una funzione separata e l’ho richiamato su documento pronto e su scroll, quindi se la pagina si aggiorna con lo scorrimento a metà della pagina, viene ridimensionata immediatamente senza dover attendere una pergamena grilletto

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

La risposta di Coops è una soluzione buona e semplice, tuttavia, una volta applicata la class fissa, la pagina diventa molto più corta e il contenuto “salta” verso l’alto, e se la pagina è di una lunghezza in cui la distanza di scorrimento è inferiore all’altezza dell’intestazione elemento, sembrerà saltare e non lasciarti vedere la parte inferiore della pagina.

La risposta che ho trovato è stata quella di aggiungere un dist spaziatore sopra l’elemento che diventerà fisso (elemento nav nel mio caso), e impostarlo alla stessa altezza dell’elemento nav e impostarlo in modo da non visualizzarne nessuno.

Quando aggiungi la class .fixed al nav, mostra il .nav-spacer div, e quando lo rimuovi, lo nascondi. Poiché l’altezza della pagina cambia istantaneamente, ho impostato la durata su 0.

HTML

 
the element above the element that will become fixed

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

Funziona perfettamente.

La soluzione scelta non si adattava bene alla mia pagina. Quindi questa è una versione più avanzata che funziona con il bootstrap.

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

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

E l’HTML

  
[....]
My header 1 My header 2

O semplicemente aggiungi un tag span con l’altezza dell’intestazione fissa impostata come altezza, quindi inseriscilo accanto all’intestazione appiccicosa:

 $(function() { var $span_height = $('.fixed-header').height; var $span_tag = ''; $('.fixed-header').after($span_tag); }); 

Speriamo che questo pezzo unico di una soluzione alternativa sia prezioso per qualcun altro come lo era per me.

Situazione :
In una pagina HTML5 avevo un menu che era un elemento di navigazione all’interno di un’intestazione (non l’intestazione THE ma un’intestazione in un altro elemento).
Volevo che la navigazione restasse nella parte superiore una volta che un utente vi si avvicinava, ma prima di ciò l’intestazione era posizionata in modo assoluto (quindi avrei potuto sovrapporre qualcos’altro leggermente).
Le soluzioni di cui sopra non hanno mai triggersto una modifica perché .offsetTop non stava per cambiare in quanto si trattava di un elemento posizionato in modo assoluto. Inoltre la proprietà .scrollTop era semplicemente la parte superiore dell’elemento più in alto … vale a dire 0 e sarebbe sempre 0.
Qualsiasi test che ho eseguito utilizzando questi due (e lo stesso risultato con getBoundingClientRect) non mi direbbe se la parte superiore della barra di navigazione sia mai stata spostata nella parte superiore della pagina visualizzabile (di nuovo, come riportato nella console, rimasero semplicemente gli stessi numeri durante lo scorrimento si è verificato).

Soluzione
La soluzione per me stava usando

 window.visualViewport.pageTop 

Il valore della proprietà pageTop riflette la sezione visualizzabile dello schermo, permettendomi quindi di tracciare dove un elemento è in riferimento ai limiti dell’area visualizzabile.
Ciò ha consentito una semplice funzione assegnata all’evento di scorrimento della finestra per rilevare quando la parte superiore della barra di navigazione si interseca con la parte superiore dell’area visibile e applicare lo stile per farlo aderire alla parte superiore.

Probabilmente non è necessario dire che ogni volta che ho a che fare con lo scroll mi aspetto di usare questa soluzione per rispondere in modo programmatico al movimento degli elementi che vengono fatti scorrere.
Spero che aiuti qualcun altro.