Jak korzystać z nowej wtyczki afiks w bootstrapie Twittera 2.1.0?

110

Dokumentacja bootstrap na ten temat jest dla mnie trochę zagmatwana. Chcę osiągnąć podobne zachowanie jak w dokumentach z afiksowym paskiem nawigacyjnym: pasek nawigacyjny znajduje się poniżej nagłówka akapitu / strony, a po przewinięciu w dół powinien najpierw przewijać, aż osiągnie górę strony, a następnie trzymać się tam, aby umożliwić dalsze przewijanie .

Ponieważ jsFiddle nie działa z koncepcją navbar, utworzyłem oddzielną stronę do użytku jako minimalny przykład: http://i08fs1.ira.uka.de/~s_drr/navbar.html

Używam tego jako mojego paska nawigacyjnego:

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

Myślę, że chciałbym data-offset-topmieć wartość 0 (ponieważ słupek powinien "trzymać się" na samej górze ", ale przy 50 jest przynajmniej jakiś efekt do obejrzenia.

Jeśli również umieść kod javascript w miejscu:

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

Każda pomoc doceniona.

Dynalon
źródło
czy próbujesz użyć affix () na głównym pasku nawigacyjnym swojej strony?
Nithin Emmanuel
@NithinEmmanuel tak, zobacz javascript w poście lub na próbce: i08fs1.ira.uka.de/~s_drr/navbar.html
Dynalon
dlaczego nie użyjesz use .navbar-fixed-topzamiast affix ()?
Nithin Emmanuel
6
@NithinEmmanuel, ponieważ nie tego chcę. .navbar-fixed-topumieściłby pasek nawigacyjny na górze przez cały czas . Chcę, aby nagłówek strony POWYŻEJ paska nawigacyjnego, a podczas przewijania w dół (a tym samym pasek nawigacyjny byłby przewijany) powinien trzymać się góry - wtedy i tylko wtedy. Dokumenty Bootstrap wykorzystywały te same mechanizmy co subnav w swoich poprzednich dokumentach, niestety usunęli go w dokumentach 2.1.0.
Dynalon
1
Po pierwsze, zagnieżdżenie JavaScript jest nieprawidłowe. )};powinno być});
Owen

Odpowiedzi:

160

Miałem podobny problem i wydaje mi się, że znalazłem lepsze rozwiązanie.

Nie zawracaj sobie głowy określaniem data-offset-topw swoim HTML. Zamiast tego określ go podczas dzwonienia .affix():

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

Zaletą jest to, że możesz zmienić układ swojej witryny bez konieczności aktualizowania data-offset-topatrybutu. Ponieważ wykorzystuje to rzeczywistą obliczoną pozycję elementu, zapobiega również niespójnościom z przeglądarkami, które renderują element w nieco innym położeniu.


Nadal będziesz musiał zacisnąć element do góry za pomocą CSS. Ponadto musiałem ustawić width: 100%element nav, ponieważ .navelementy z position: fixedjakiegoś powodu źle się zachowują:

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

I ostatnia rzecz: kiedy przymocowany element zostaje unieruchomiony, jego element nie zajmuje już miejsca na stronie, co powoduje, że elementy pod nim „skaczą”. Aby zapobiec tej brzydocie, zawijam pasek nawigacyjny tak, aby divjego wysokość była równa paskowi nawigacyjnemu w czasie wykonywania:

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

.

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

Oto obowiązkowy jsFiddle, aby zobaczyć go w akcji .

namuol
źródło
6
Świetna wskazówka, jak usunąć „skok” - całkowicie przeoczyłem fakt, że ten element został usunięty i pomyślałem, że mój problem jest zawarty w części z przyrostkiem / js mojego kodu.
Thomas
1
Ta odpowiedź jest najlepsza! Wszystko działa jak powinno. W większości samouczków, które znalazłem, brakowało części „skok”. Dzięki!
Ricardo Otero
1
Jedna ważna poprawka: użyj offset () zamiast position () w kodzie jQuery w pierwszym fragmencie kodu. Objaśnienie: Funkcja position () podaje przesunięcie w elemencie nadrzędnym, ale offset () to jego pozycja w dokumencie, czyli tak, jak chcesz (tak, nazwy są sprzeczne z intuicją). Więc twój kod nie działałby, gdyby twój element afiks był wewnątrz innego elementu. Powinieneś także przekazać tylko wartość "top" w ten sposób: $ ("# nav"). Affix ({offset: {top: $ ('# nav'). Offset (). Top. I powinno znajdować się wewnątrz gotowego () blok, abyś wiedział, że układ strony jest kompletny.
orrd
Dzięki @orrd - Aktualizuję moją odpowiedź i skrzypce!
namuol
Miły! Działa doskonale i jest bardzo płynny. Nawiasem mówiąc, szukam tego samego przykładu z lepką stopką. Jeśli wiesz, jak to zrobić, czy możesz zaktualizować jsFiddle? Dzięki!
Jocelyn
76

Właśnie zaimplementowałem to po raz pierwszy i oto co znalazłem.

data-offset-topWartość to ilość pikseli, które trzeba przewijać w celu umieszczania efektu nastąpić. W twoim przypadku, po 50pxprzewinięciu, klasa twojego przedmiotu zostanie zmieniona z .affix-topna .affix. Prawdopodobnie chciałbyś zająć data-offset-topsię 130pxswoim przypadkiem użycia.

Gdy nastąpi zmiana klasy, musisz ustawić swój element w css, określając styl dla klasy .affix. Bootstrap 2.1 już definiuje .affixjako position: fixed;więc wszystko co musisz zrobić, to dodać własne wartości pozycji.

Przykład:

.affix {
    position: fixed; 
    top: 20px; 
    left: 0px;
}
Dave Kiss
źródło
1
Dzięki, to trochę działa. Zaktualizowałem do tego moją przykładową stronę. Problem w tym, że gdy tylko navbar otrzyma „przyrostek” jako klasa css, klasa css navbar jest odrzucana. ale myślę, że to tylko błąd / niedociągnięcie z bootstrapa. Zmiana nie będzie łatwa bez zrobienia tego w MNIEJ i odbudowania bootstrapu.
Dynalon
Wydaje mi się, że .navbarklasa jest zachowana - czy na pewno?
Dave Kiss
Dzięki za tę odpowiedź, spędziłem całe wieki próbując to
rozgryźć
Zobacz moją odpowiedź na nieco ulepszone, bardziej ogólne rozwiązanie.
namuol
5

Aby rozwiązać ten problem, zmodyfikowałem wtyczkę affix, aby emitowała zdarzenie jQuery, gdy obiekt jest przymocowany lub nie jest naprawiony.

Oto żądanie ściągnięcia: https://github.com/twitter/bootstrap/pull/4712

Oraz kod: https://github.com/corbinu/bootstrap/blob/master/js/bootstrap-affix.js

A następnie zrób to, aby dołączyć pasek nawigacyjny:

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

    $('#navbar').on('unaffixed', function () {
        $('#navbar').removeClass('navbar-fixed-top')
    });
});
</script>
Corbin U
źródło
3

Musisz usunąć .affix()ze swojego skryptu.

Bootstrap przez data-attributeswiększość czasu daje możliwość wykonywania zadań za pomocą lub bezpośrednio w JavaScript.

Patrick Laughlin
źródło
2

Mam to z kodu źródłowego twitterbootstrap i działa całkiem nieźle:

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);
});
Jesus Rodriguez
źródło
1

Musisz tylko usunąć skrypt. Oto mój przykład:

<!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>
Beckovsky
źródło
1

Dzięki namuol i Dave Kiss za rozwiązanie. W moim przypadku miałem mały problem z wysokością i szerokością paska nawigacyjnego, gdy użyłem razem wtyczek afflix i collapse. Problem z szerokością można łatwo rozwiązać dziedzicząc ją po elemencie nadrzędnym (w moim przypadku kontenera). Mogłem również sprawić, że upadnie płynnie za pomocą odrobiny JavaScript (właściwie coffeescript). Sztuczka polega na tym, aby ustawić wysokość opakowania autoprzed wystąpieniem przełączenia zwinięcia i naprawić ją ponownie po.

Znacznik (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()
Voldy
źródło
0

Moje rozwiązanie do dołączenia paska nawigacyjnego:

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();
        });
 }
Florian
źródło
0

Podobnie jak w przypadku zaakceptowanej odpowiedzi, możesz również wykonać następujące czynności, aby zrobić wszystko za jednym razem:

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

Spowoduje to nie tylko wywołanie affixwtyczki, ale także zawinie przymocowany element do elementu div, który zachowa oryginalną wysokość paska nawigacyjnego.

Adrian
źródło