2013-05-13 14 views
10

Ho un problema specifico nel creare un'intestazione appiccicosa con jQuery. Ho provato i frammenti comunemente usati in giro per il web, ma ho percepito la stessa cosa buggy ovunque.Sticky Header - buggy jumping on scroll

A un'altezza di documento specifica (scorrevole fino a un po 'più di chiamata di effetto appiccicoso) l'intestazione appiccicosa salta tra position: fixed e position: static.

HTML:

<header> 
    <div id="not-sticky"></div> 
    <div id="sticky"></div> 
</header> 
<div id="content"> ... 


jQuery:

var $sticky = $("#sticky"); 
var offset = $sticky.offset(); 
var stickyTop = offset.top; 
var windowTop = $(window).scrollTop(); 
$(window).scroll(function() { 
    windowTop = $(window).scrollTop(); 
    if (windowTop > stickyTop) { 
    $sticky.css({ 
     position: 'fixed', 
     top: 0 
    }); 
    } 
    else { 
    $sticky.css({ 
     position: '', 
     top: '' 
    }); 
    } 
}); 


CSS:

header { 
    width: 100%; 
} 

#not-sticky { 
    padding: 50px 0; 
    width: 100%; 
} 

#sticky { 
    padding: 24px 0; 
    position: relative; 
    width: 100%; 
    z-index: 25; 
} 


Ho anche provato un margine inferiore su #not-sticky con la stessa altezza dello #sticky per mantenere un'altezza di documento costante, ma si è verificato lo stesso effetto di appiccicosità.

Qualche idea per aggiustare quella cosa?

risposta

13

Scatta il fuoco troppe volte e provando a impostare un elemento style sarà sempre & creare inevitabilmente dei salti (anche a malapena visibili ma comunque scomposti).

Il modo migliore che ho trovato è quello di

  1. clone nostro elemento,
  2. marca che clone fixed
  3. gioco con lo stile di clone visibility.

JS Pure:

;(function(){ /* STICKY */ 
 

 
    var sticky = document.getElementById("sticky"), 
 
     sticky2 = sticky.cloneNode(true); 
 

 
    sticky2.style.position = "fixed"; 
 
    document.body.appendChild(sticky2); 
 

 
    function stickIt(){ 
 
    sticky2.style.visibility = sticky.getBoundingClientRect().top<0 ? "visible" : "hidden"; 
 
    } 
 

 
    stickIt(); 
 
    window.addEventListener("scroll", stickIt, false); 
 
}());
#sticky{ 
 
    height:100px; 
 
    background:#ada; 
 
    height:50px; 
 
    position:relative; 
 
    /* needed for clone: */ 
 
    top:0; 
 
    width:100%; 
 
} 
 

 

 
/* Just for this demo: */ 
 
*{margin:0;padding:0;} 
 
#content{height:2000px; border:3px dashed #444;} 
 
h1{padding:40px; background:#888;}
<h1>Logo</h1> 
 
<div id="sticky">Sticky header</div> 
 
<div id="content">Lorem ipsum...<br>bla bla</div>

Quindi, quando si vede il "header" fix, che in realtà è il nostro clone fisso sempre visibile on-top.

+0

Grazie amico, funziona benissimo! Speravo che sarebbe stato possibile senza un div wrapping per mantenere un markup pulito, ma lo incoraggerò. –

+0

@TimoM sei il benvenuto! Ho creato una funzione riutilizzabile per poterla usare anche su 'DOM ready',' window load', ovunque sia necessario. Sai, le immagini si caricano lentamente e potrebbero essere utili per ricontrollare il valore di scorrimento, poiché a volte la pagina potrebbe essere già visualizzata mentre è visitata. –

+0

Sì, grazie per quello! Ho già avvolto jQuery nel 'DOM ready', ma questa funzione' sticky() 'è davvero bella! –