Come utilizzare il nuovo plug-in di affisso nel bootstrap 2.1.0 di Twitter?


110

La documentazione bootstrap su questo argomento è un po 'confusa per me. Voglio ottenere un comportamento simile come nei documenti con l'apposizione barra di navigazione: la barra di navigazione si trova sotto un'intestazione di paragrafo / pagina e, scorrendo verso il basso, dovrebbe prima scorrere fino a raggiungere la parte superiore della pagina, quindi rimanere fissata lì fissa per ulteriori scorrimenti .

Poiché jsFiddle non funziona con il concetto di barra di navigazione, ho impostato una pagina separata da utilizzare come esempio minimo: http://i08fs1.ira.uka.de/~s_drr/navbar.html

Lo uso come barra di navigazione:

<div class="navbar affix-top" data-spy="affix" data-offset-top="50">
    <div class="navbar-inner">
        <div class="container">
            <div class="span12">
                <a class="brand" href="#">My Brand</a> 
                This is my navbar.
             </div>
        </div> <!-- container -->
    </div> <!-- navbar-inner -->
</div> <!-- navbar -->

Penso che vorrei data-offset-topessere di valore 0 (poiché la barra dovrebbe "restare" in alto "ma con 50 c'è almeno qualche effetto guardabile.

Se inserisci anche il codice javascript:

     <script>
        $(document).ready (function (){
            $(".navbar").affix ();
        });
     </script>

Qualsiasi aiuto apprezzato.


stai cercando di usare affix () sulla barra di navigazione principale della tua pagina?
Nithin Emmanuel

@NithinEmmanuel sì, guarda il javascript nel post o nell'esempio
Dynalon

perché non usi use .navbar-fixed-topinvece di usare affix ()?
Nithin Emmanuel

6
@ NithinEmmanuel perché non è quello che voglio. .navbar-fixed-topavrebbe posto la barra di navigazione verso l'alto per tutto il tempo . Voglio un'intestazione di pagina SOPRA la barra di navigazione, e quando scorri verso il basso (e quindi la barra di navigazione scommetterebbe scorrendo via) dovrebbe rimanere in alto, allora e solo allora. I documenti di Bootstrap hanno utilizzato gli stessi meccanismi di una sottonav nei loro documenti precedenti, purtroppo l'hanno rimosso per i documenti 2.1.0.
Dynalon

1
Per uno, la nidificazione del tuo Javascript non è corretta. )};dovrebbe essere});
Owen

Risposte:


160

Avevo un problema simile e credo di aver trovato una soluzione migliore.

Non preoccuparti di specificare data-offset-topnel tuo HTML. Invece, specificalo quando chiami .affix():

$('#nav').affix({
    offset: { top: $('#nav').offset().top }
});​

Il vantaggio qui è che puoi modificare il layout del tuo sito senza dover aggiornare l' data-offset-topattributo. Poiché utilizza la posizione calcolata effettiva dell'elemento, previene anche incongruenze con i browser che rendono l'elemento in una posizione leggermente diversa.


Sarà comunque necessario bloccare l'elemento in alto con CSS. Inoltre, ho dovuto impostare width: 100%l'elemento nav poiché gli .navelementi con un position: fixedcomportamento anomalo per qualche motivo:

#nav.affix {
    position: fixed;
    top: 0px;
    width: 100%;
}

Un'ultima cosa: quando un elemento apposto diventa fisso, il suo elemento non occupa più spazio sulla pagina, provocando il "salto" degli elementi sottostanti. Per evitare questa bruttezza, avvolgo la barra di navigazione in una la divcui altezza ho impostato essere uguale alla barra di navigazione in fase di esecuzione:

<div id="nav-wrapper">
    <div id="nav" class="navbar">
        <!-- ... -->
    </div>
</div>

.

$('#nav-wrapper').height($("#nav").height());

Ecco il jsFiddle obbligatorio per vederlo in azione .


6
Ottimo consiglio per rimuovere il "salto": ho completamente trascurato il fatto che questo elemento viene rimosso e ho pensato che il mio problema fosse contenuto nella parte affix / js del mio codice.
Thomas,

1
Questa risposta è la migliore! Tutto funziona come dovrebbe. La parte "salta" era quella mancante nella maggior parte dei tutorial che ho trovato. Grazie!
Ricardo Otero

1
Una correzione importante: usa offset () invece di position () nel codice jquery nel tuo primo frammento di codice. Spiegazione: La funzione position () ti dà l'offset all'interno dell'elemento genitore, ma offset () è la sua posizione all'interno del documento, che è quello che vuoi veramente (sì, i nomi sono contro-intuitivi). Quindi il tuo codice non funzionerebbe se il tuo elemento di affisso si trova all'interno di un altro elemento. Dovresti anche passare solo il valore "top" in questo modo: $ ("# nav"). Affix ({offset: {top: $ ('# nav'). Offset (). Top. E dovrebbe essere all'interno di un file ready () in modo da sapere che il layout della pagina è completo.
orrd

Grazie @orrd - Aggiornamento della mia risposta e violino!
namuol

Bello! Funziona perfettamente ed è molto fluido. A proposito, sto cercando lo stesso esempio con un piè di pagina appiccicoso. Se sai come farlo, puoi aggiornare jsFiddle? Grazie!
Jocelyn

76

L'ho appena implementato per la prima volta ed ecco cosa ho trovato.

Il data-offset-topvalore è la quantità di pixel che è necessario scorrere affinché abbia luogo l'effetto di apposizione. Nel tuo caso, una volta fatto 50pxscorrere, la classe sul tuo elemento viene modificata da .affix-topa .affix. Probabilmente vorrai impostare data-offset-topcirca 130pxnel tuo caso d'uso.

Una volta che si verifica questo cambio di classe, devi posizionare il tuo elemento in css definendo il posizionamento per la classe .affix. Bootstrap 2.1 definisce già .affixcome position: fixed;modo tutto quello che dovete fare è aggiungere i propri valori di posizione.

Esempio:

.affix {
    position: fixed; 
    top: 20px; 
    left: 0px;
}

1
Grazie, in qualche modo funziona. Ho aggiornato la mia pagina di esempio a quello. Il problema è ora, non appena la navbar ottiene "affisso" come classe CSS, la classe CSS navbar viene scartata. ma penso che sia solo un bug / difetto di bootstrap. Non sarà facile cambiare senza farlo in LESS e ricostruire il bootstrap.
Dynalon

Mi sembra che la .navbarclasse sia preservata, sei sicuro?
Dave Kiss

Grazie per questa risposta, ho passato anni a cercare di capirlo
Reuben

Vedi la mia risposta per una soluzione leggermente migliorata e più generale.
namuol

5

Per risolvere questo problema, ho modificato il plug-in affix per emettere un evento jQuery quando un oggetto è apposto o non apposto.

Ecco la richiesta di pull: https://github.com/twitter/bootstrap/pull/4712

E il codice: https://github.com/corbinu/bootstrap/blob/master/js/bootstrap-affix.js

E poi fallo per collegare la barra di navigazione:

<script type="text/javascript">
$(function(){
    $('#navbar').on('affixed', function () {
        $('#navbar').addClass('navbar-fixed-top')
    });

    $('#navbar').on('unaffixed', function () {
        $('#navbar').removeClass('navbar-fixed-top')
    });
});
</script>

3

Devi rimuovere .affix()dal tuo script.

Bootstrap offre la possibilità di realizzare cose tramite data-attributeso direttamente JavaScript la maggior parte del tempo.


2

L'ho preso dal codice sorgente di twitterbootstrap e funziona abbastanza bene:

HTML:

<div class="row">
    <div class="span3 bs-docs-sidebar">
        <ul id="navbar" class="nav nav-list bs-docs-sidenav">
            ...
        </ul>
    </div>
</div>

CSS:

.bs-docs-sidenav {
    max-height: 340px;
    overflow-y: scroll;
}

.affix {
    position: fixed;
    top: 50px;
    width: 240px;
}

JS:

$(document).ready(function(){
    var $window = $(window);
    setTimeout(function () {
        $('.bs-docs-sidenav').affix({
            offset: {
                top: function (){
                    return $window.width() <= 980 ? 290 : 210
                }
            }
        })
    }, 100);
});

1

Hai solo bisogno di rimuovere lo script. Ecco il mio esempio:

<!DOCTYPE html>
<html>

<head>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.8.0.min.js"></script>
<script type="text/javascript" src="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.1.0/js/bootstrap.min.js"></script>

  <style>
  #content {
    width: 800px;
    height: 2000px;
    background: #f5f5f5;
    margin: 0 auto;
  }
  .menu {
    background: #ccc;
    width: 200px;
    height: 400px;
    float: left;
  }
  .affix {
    position: fixed;
    top: 20px;
    left: auto;
    right: auto;
  }
  </style>

</head>
<body>
    <div id="content">
        <div style="height: 200px"></div>

        <div class="affix-top" data-spy="affix" data-offset-top="180">
            <div class="menu">AFFIX BAR</div>
        </div>
    </div>
</body>
</html>

1

Grazie a namuol e Dave Kiss per la soluzione. Nel mio caso ho avuto un piccolo problema con l'altezza e la larghezza della barra di navigazione quando ho usato afflix e collapse plugin insieme. Il problema con la larghezza può essere facilmente risolto ereditandolo dall'elemento genitore (container nel mio caso). Inoltre sono riuscito a farlo collassare senza problemi con un po 'di javascript (coffeescript in realtà). Il trucco è impostare l'altezza dell'involucro su autoprima che si verifichi l'attivazione / disattivazione del collasso e correggerla dopo.

Markup (haml):

#wrapper
  #navbar.navbar
    .navbar-inner
      %a.btn.btn-navbar.btn-collapse
        %span.icon-bar
        %span.icon-bar
        %span.icon-bar

      #menu.nav-collapse
        -# Menu goes here

CSS:

#wrapper {
  width: inherit;
}

#navbar {
  &.affix {
    top: 0;
    width: inherit;
  }
}

CoffeeScript:

class Navigation
  @initialize: ->
    @navbar = $('#navbar')
    @menu = $('#menu')
    @wrapper = $('#wrapper')

    @navbar.affix({offset: @navbar.position()})
    @adjustWrapperHeight(@navbar.height())

    @navbar.find('a.btn-collapse').on 'click', () => @collapse()

    @menu.on 'shown', () => @adjustWrapperHeight(@navbar.height())
    @menu.on 'hidden', () => @adjustWrapperHeight(@navbar.height())

  @collapse: ->
    @adjustWrapperHeight("auto")
    @menu.collapse('toggle')

  @adjustWrapperHeight: (height) ->
    @wrapper.css("height", height)

$ ->
  Navigation.initialize()

0

La mia soluzione per collegare la barra di navigazione:

function affixnolag(){

    $navbar = $('#navbar');
    if($navbar.length < 1)
        return false;

    h_obj = $navbar.height();

    $navbar
        .on('affixed', function(){      
            $navbar.after('<div id="nvfix_tmp" style="height:'+h_obj+'px">');
        })
        .on('unaffixed', function(){
            if($('#nvfix_tmp').length > 0)
                $('#nvfix_tmp').remove();
        });
 }

0

Simile alla risposta accettata, puoi anche fare qualcosa come il seguente per fare tutto in una volta:

$('#nav').affix({
  offset: { top: $('#nav').offset().top }
}).wrap(function() {
  return $('<div></div>', {
    height: $(this).outerHeight()
  });
});​

Questo non solo richiama il affixplugin, ma avvolge anche l'elemento apposto in un div che manterrà l'altezza originale della barra di navigazione.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.