2012-02-15 10 views
88

Ho un sito con la barra di navigazione fissata in alto e 3 div al di sotto nell'area di contenuto principale.Come si imposta l'offset per ScrollSpy in Bootstrap?

Sto provando a usare scrollspy dal framework di bootstrap.

Ho evidenziato con successo le diverse intestazioni nel menu quando si scorre oltre i div.

Ho anche così quando si fa clic sul menu, scorrerà fino alla parte corretta della pagina. Tuttavia, l'offset non è corretto (non è tenuto conto della barra di navigazione, quindi ho bisogno di compensato da circa 40 pixel)

vedo sul Bootstrap page si parla di un'opzione di offset, ma non sono sicuro come utilizzare esso.

Non sono nemmeno quello che significa quando si dice che è possibile usare scrollspy con $('#navbar').scrollspy(), non sono sicuro dove includerlo, così non l'ho fatto e tutto sembra funzionare (eccetto l'offset).

Ho pensato che l'offset potrebbe essere il data-offset='10' sul tag del corpo, ma non fa nulla per me.

Ho la sensazione che questa sia una cosa ovvia e mi manca. Qualsiasi aiuto?

mio codice è

... 
<!-- note: the data-offset doesn't do anything for me --> 
<body data-spy="scroll" data-offset="20"> 
<div class="navbar navbar-fixed-top"> 
<div class="navbar-inner"> 
    <div class="container"> 
    <a class="brand" href="#">VIPS</a> 
    <ul class="nav"> 
     <li class="active"> 
      <a href="#trafficContainer">Traffic</a> 
     </li> 
     <li class=""> 
     <a href="#responseContainer">Response Times</a> 
     </li> 
     <li class=""> 
     <a href="#cpuContainer">CPU</a> 
     </li> 
     </ul> 
    </div> 
</div> 
</div> 
<div class="container"> 
<div class="row"> 
    <div class="span12"> 
    <div id="trafficContainer" class="graph" style="position: relative;"> 
    <!-- graph goes here --> 
    </div> 
    </div> 
</div> 
<div class="row"> 
    <div class="span12"> 
    <div id="responseContainer" class="graph" style="position: relative;"> 
    <!-- graph goes here --> 
    </div> 
    </div> 
</div> 
<div class="row"> 
    <div class="span12"> 
    <div id="cpuContainer" class="graph" style="position: relative;"> 
    <!-- graph goes here --> 
    </div> 
    </div> 
</div> 
</div> 

... 
<script src="assets/js/jquery-1.7.1.min.js"></script> 
<script src="assets/js/bootstrap-scrollspy.js"></script> 
</body> 
</html> 
+0

Perché stai dando una posizione: relativa alle tue div? Forse questo è ciò che sta causando questo. Puoi creare un jsfiddle con il tuo codice in modo che possiamo vedere in azione? – periklis

risposta

100

Bootstrap utilizza l'offset per risolvere solo lo spionaggio, non lo scorrimento. Ciò significa che lo scorrimento verso il posto giusto dipende da te.

Prova questo, funziona per me: aggiungi un gestore di eventi per i clic di navigazione.

var offset = 80; 

$('.navbar li a').click(function(event) { 
    event.preventDefault(); 
    $($(this).attr('href'))[0].scrollIntoView(); 
    scrollBy(0, -offset); 
}); 

ho trovato qui: https://github.com/twitter/bootstrap/issues/3316

+3

Grazie per la risposta. Mi ci è voluto un po 'per capire che l'offset non influisce sullo scorrimento. Ciò significa che chiunque usi un top fisso deve adattarsi manualmente in questo modo. –

+8

Per aggiornare la sezione dell'hash dell'URL in modo appropriato, aggiungere 'window.location.hash = $ (this) .attr ('href')' a questa funzione. –

+2

Grazie! FWIW, anche l'offset dei dati nel corpo è importante, in quanto il richiedente dice di non fare nulla, ma è necessario per spionaggio adeguato. Potrebbe essere utile avere una risposta esauriente. – mrooney

8

Se si desidera un offset di 10 si potrebbe mettere questo nella tua testa:

<script> 
    $('#navbar').scrollspy({ 
    offset: 10 
    }); 
</script> 

Il tag corpo sarebbe simile a questa:

<body data-spy="scroll"> 
+5

Ciò non compensa il contenuto, compensa il nav. – markus

+1

Che non ha funzionato ... – Turbojohan

+0

Questo funzionerà per evidenziare l'elemento nav corretto e non la posizione in cui il click conduce (che è la domanda originale dei poster). Detto questo, questo era quello che stavo cercando! Grazie! – valin077

1

Penso che l'offset possa fare qualcosa con la posizione in basso della sezione.

Ho risolto il mio problema - uguali ai suoi - con l'aggiunta di

padding-top: 60px; 

nella dichiarazione per la sezione in bootstrap.css

Speranza che aiuta!

+0

cosa è una "dichiarazione per sezione" Dove metti questo codice? – ahnbizcad

70

Il trucco, come Tim accennato, è quello di approfittare di imbottitura. Quindi il problema è che il tuo browser vuole sempre far scorrere l'ancora fino alla cima della finestra. se imposti il ​​punto di ancoraggio nel punto in cui inizia effettivamente il testo, verrà bloccato dalla barra dei menu. Invece, ciò che fai è impostare l'ancoraggio al contenitore <section> o <div> ID del tag, che verrà utilizzato automaticamente da nav/navbar.Quindi devi impostare il tuo padding-top per il contenitore sull'offset desiderato e il margin-top per il contenitore allo di fronte allo dello padding-top. Ora il blocco del contenitore e l'ancoraggio iniziano nella parte superiore esatta della pagina, ma il contenuto all'interno non inizia fino a sotto la barra dei menu.

Se si utilizzano ancoraggi regolari, è possibile ottenere lo stesso risultato utilizzando il margine negativo superiore nel contenitore come sopra, ma senza riempimento. Quindi inserisci un ancoraggio <a target="..."> regolare come primo figlio del contenitore. Quindi si disegna il secondo elemento figlio con un valore opposto ma uguale a margin-top, ma utilizzando il selettore .container:first-child +.

Tutto questo presuppone che il tag <body> abbia già il suo margine impostato per iniziare sotto l'intestazione, che è la norma (altrimenti la pagina eseguirà il rendering con testo occluso direttamente dal blocco).

Ecco un esempio di questo in azione. Qualsiasi cosa sulla tua pagina con un ID può essere collegata inserendo # the-elements-id alla fine del tuo URL. Se si apportano tutti i tag ht tag ht con ID in grado di collegare (Like github does) con some sort of script that injects a little link to the left of them; aggiungendo quanto segue al vostro CSS si prenderà cura di l'offset per voi nav-bar:

body { 
    margin-top: 40px;/* make room for the nav bar */ 
} 

/* make room for the nav bar */ 
h1[id], 
h2[id], 
h3[id], 
h4[id], 
h5[id], 
h6[id], 
dt[id]{ 
    padding-top: 60px; 
    margin-top: -40px; 
} 
+8

Love the padding-top, negativo margin-bottom (sullo stesso elemento) combo .Più facile quindi scherzare con il js. – Eystein

+2

Questa è un'ottima risposta. Nota anche per impostare l'offset dei dati. – ken

+1

Questa è una bellezza assoluta di una soluzione alternativa. – hydrogen

8

È possibile modificare l'offset del scrollspy al volo con questo (supponendo che si spiare sul corpo):

offsetValue = 40; 
$('body').data().scrollspy.options.offset = offsetValue; 
// force scrollspy to recalculate the offsets to your targets 
$('body').data().scrollspy.process(); 

Questo funziona anche se è necessario modificare il valore di offset in modo dinamico. (Mi piace lo scrollspy di passare quando la sezione successiva è circa a metà della finestra, così ho bisogno di cambiare l'offset durante la finestra di ridimensionamento.)

+2

Grazie per questo - funziona alla grande con un piccolo aggiustamento per Bootstrap 3.0 $ ('body'). Data() ['bs.scrollspy']. Options.offset = newOffset; // Imposta il nuovo offset $ ('body'). Data() ['bs.scrollspy']. Process(); // Forza scrollspy per ricalcolare gli offset delle destinazioni $ ('body'). Scrollspy ('refresh'); // Aggiorna lo scrollspy. – Sam

+0

Ho trovato che questo metodo è buono, ma che se voglio usarlo per impostare l'offset dall'inizio a causa dell'altezza di menu diversa, $ ('body'). Data(). Scrollspy.options.offset (o la variante per la versione 3.0) non è ancora impostata. C'è qualcosa di asincrona nello scrollspy che mi manca? –

+0

A partire da Bootstrap 3.1.1 questo dovrebbe essere '$ ('body'). Data() ['bs.scrollspy']. Options.offset'. Utile per attivare lo scrollspy sul caricamento della pagina usando 'window.scrollBy (X, Y)' – Meredith

1

ho aggiunto 40px altezza .vspace elemento tenendo l'ancora prima di ciascuno dei miei h1 elementi .

<div class="vspace" id="gherkin"></div> 
<div class="page-header"> 
    <h1>Gherkin</h1> 
</div> 

Nel CSS:

.vspace { height: 40px;} 

E 'di lavoro grande e lo spazio non è soffocamento.

0

Ho avuto problemi con le soluzioni di acjohnson55 e Kurt UXD. Entrambi hanno funzionato per fare clic su un collegamento all'hash, ma l'offset scrollspy non era ancora corretto.

mi si avvicinò con la seguente soluzione:

<div class="anchor-outer"> 
    <div id="anchor"> 
    <div class="anchor-inner"> 
     <!-- your content --> 
    </div> 
    </div> 
</div> 

e il corrispondente CSS:

body { 
    padding-top:40px; 
} 

.anchor-outer { 
    margin-top:-40px; 
} 

.anchor-inner { 
    padding-top:40px; 
} 

@media (max-width: 979px) { 
    body { 
    padding-top:0px; 
    } 

    .anchor-outer { 
    margin-top:0px; 
    } 

    .anchor-inner { 
    padding-top:0px; 
    } 
} 

@media (max-width: 767px) { 
    body { 
    padding-top:0px; 
    } 

    .anchor-outer { 
    margin-top:0px; 
    } 

    .anchor-inner { 
    padding-top:0px; 
    } 
} 

Sarà necessario sostituire il 40px padding/margine con l'altezza della vostra barra di navigazione, e la id della tua ancora.

In questa configurazione è possibile osservare un effetto dell'impostazione di un valore per l'attributo di offset dei dati. Se si trovano valori elevati per l'offset dei dati intorno a 100-200, si ottiene un comportamento più atteso (lo scrollspy- "interruttore" si verificherà se l'intestazione è circa nel mezzo dello schermo).

Ho anche scoperto che lo scrollspy è molto sensibile ad errori come i tag div non chiusi (il che è abbastanza ovvio), quindi http://validator.w3.org/check era mio amico qui.

A mio parere, lo scrollspy funziona meglio con intere sezioni che trasportano l'ID di ancoraggio, poiché gli elementi di ancoraggio regolari non portano a effetti previsti quando si scorre all'indietro (lo scrollspy- "switch" alla fine si verifica non appena si colpisce l'elemento di ancoraggio, ad es. il tuo titolo, ma in quel momento hai già fatto scorrere il contenuto che l'utente si aspetta di appartenere al titolo corrispondente).

-1

È anche possibile aprire e modificare bootstap-offset.js

$.fn.scrollspy.defaults = { 
    offset: 10 
} 

lì.

+1

L'offset scrollspy non compensa il contenuto, compensa il nav. – markus

2

Da bootstrap issue #3316:

[Questo] è destinato esclusivamente per modificare i calcoli di scorrimento - noi non spostiamo l'ancora attuale click

Così impostazione di offset riguarda solo dove scrollspy pensa pagina si scorre a. Lo standard non influisce sullo scorrimento di quando si fa clic su un tag di ancoraggio.

L'utilizzo di una barra di navigazione fissa indica che il browser sta scorrendo nel posto sbagliato. È possibile risolvere questo con JavaScript:

var navOffset = $('.navbar').height(); 

$('.navbar li a').click(function(event) { 
    var href = $(this).attr('href'); 

    // Don't let the browser scroll, but still update the current address 
    // in the browser. 
    event.preventDefault(); 
    window.location.hash = href; 

    // Explicitly scroll to where the browser thinks the element 
    // is, but apply the offset. 
    $(href)[0].scrollIntoView(); 
    window.scrollBy(0, -navOffset); 
}); 

Tuttavia, per garantire che scrollspy evidenzia l'elemento corrente corretta, è ancora necessario impostare l'offset:

<body class="container" data-spy="scroll" data-target=".navbar" data-offset="70"> 

Ecco a complete demo on JSFiddle.


alternativa, si potrebbe imbottitura ai tag di ancoraggio, come suggested by CSS tricks.

a[id]:before { 
    display: block; 
    content: " "; 
    // Use the browser inspector to find out the correct value here. 
    margin-top: -285px; 
    height: 285px; 
    visibility: hidden; 
} 
-1

Basta impostare:

data-offset="200" 

data-offset è di default "50" e cioè 10px equivalente, quindi basta aumentare data-offset e il problema è risolto.

Problemi correlati